Development of a gas optimization system for transactions

Transactions become more expensive during peak load, and the execution costs of operations rise along with them. We develop a turnkey gas optimization system: we measure, configure execution modes, and hand over procedures. The client gets predictable operation costs and a reduction in expenses by multiple times.

Blockchain Development Services

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

Gas optimization: where transactions lose efficiency

The cost of a transaction on an Ethereum-based network consists of three components: computational work, the volume of state writes, and current network load. The same function costs the user differently during quiet and peak periods.

Therefore, gas optimization is not a one-time fix, but work with the execution profile and hot paths.

The first and most common source of overspending is the contract itself.

A loop that iterates over the entire array for a single element, reading from state on every iteration instead of moving the value into memory, writing to storage where a local variable would suffice — each such line is multiplied by the number of calls.

Add duplicate checks and data structures chosen without measurement, and you get a contract that costs many times more than necessary.

The second source is network load and client application behavior. When the base fee rises, a transaction either waits in the queue or executes exactly until the point where gas runs out.

Failed operations have already consumed gas: the user pays for the revert and repeats the call at the new price. The third source is unsuccessful retries with the same limit that again hit the same ceiling.

We examine how this is addressed: where to take measurements, which paths to rewrite first, and how to structure retry logic so it does not waste gas.

What gas optimization delivers: measurable effects

Gas optimization is not a fix to a single function, but a set of decisions: how data is packed in contract calls, which execution branches are more expensive than others, and where an operation will hit the block gas limit.

We work with Ethereum-compatible networks and measure the effect before and after — by metrics, not by feel. Below are five results the client gets.

Lower execution costs

The cost of a typical operation drops through repacking structures, reusing already-read values, and moving heavy computations off-chain. Gas consumption per scenario is reduced by 2–4 times with the same result.

Share of successful operations

We calculate the cost estimate for a specific scenario, with a buffer for state changes, rather than "by eye." The share of operations reaching confirmation on the first attempt grows from 80–85% to 97% and higher.

Confirmation time

Accurate estimation and correct priority eliminate queue waiting and overpayments for acceleration. An operation gets into a block in the first or second interval instead of being resent.

Transaction failures

We separately address classes of failures: state races, gas limit exhaustion, and external call failures. Resends and lost operations disappear from the statistics.

Load predictability

Per-operation limits, a queue, and a peak profile make the load predictable. A spike in activity does not make each subsequent operation more expensive and does not stop processing.

Transaction execution modes: comparison of approaches

The sending mode determines not only the cost of a single operation, but also how the system is maintained.

It determines where to place retries on failure, how to calculate nonces between wallets, and what to do during peak network load — when the price of inclusion in a block grows several times within minutes.

Organization option When it fits Scheme limitations
Single sends with manual parameter tuning One-off high-value operations, test environments Does not scale: the operator becomes a bottleneck, and when the network is slow, the operation "hangs" without automatic retry
Continuous stream with automatic fee estimation Steady load: a predictable number of operations per hour Overpayment for reserve during quiet periods; during peaks, estimation lags, and some operations are pushed out of the queue
Batch processing with calls combined into one operation Mass identical actions: payouts, registrations, token issuance Failure of one call reverts the entire batch; part of the gas goes to auxiliary checks, and batch size is limited by block size
Transaction queue with priorities and nonce control High load, a stream of events from external systems Requires separate queue state storage and monitoring: nonce desynchronization stops the entire stream

The choice between schemes is a trade-off between cost and manageability, and it is not made once at the start. We begin with measurements on a real load profile: the distribution of operations by hour, the share of dropped transactions, and queue behavior during peaks.

After that, we lock in the mode and keep parameters configurable — as the stream grows, batch processing is supplemented with a priority queue without rewriting the logic.

Implementation stages: from measurements to handover of procedures

Gas optimization begins not with code changes, but with measuring how the stream of operations actually consumes gas. Until there is a breakdown by calls, any change is guesswork, not engineering. We run the project in six stages, and each ends with an artifact that can be verified.

  1. Transaction audit. We export the call history for a period, break down consumption by method, and separately calculate the three components: storage writes, computations, and transmitted data. The output is a list of operations that account for the main share of consumption.
  2. Processing scheme. We build a map of the operation flow: where state is written repeatedly, where checks are duplicated, and which calls can be combined into one or moved off-chain.
  3. Contract tuning. We pack fields into shared slots, move computations from storage to memory, cache repeated accesses, and set limits on mass operations.
  4. Test environment. We deploy a copy of the network state and run scenarios with the same load profile. We compare consumption by each method with the baseline — discrepancies in scenarios are visible before release.
  5. Before-and-after measurements. We record the cost of one operation in gas, not "on average across the system": a report with a breakdown by method and the share that was removed from the critical path.
  6. Rollout and handover of procedures. We roll out changes across environments and hand over the rules: which thresholds count as a deviation, how to roll back to the previous version, and what to check before each release.

After handover, the measurements remain with your team — consumption by method can be checked at every release, rather than finding out after the fact why operations became more expensive.

Handover package: configurations, schemes, procedures

The handover package is not an archive of files, but a set of artifacts your team can use to operate the gas optimization system independently: change thresholds, deploy the environment in a new setting, and investigate incidents without our involvement. Below is what exactly is handed over along with the working environment.

  • Calculation configurations: target cost parameters, per-transaction limits, grouping and prioritization rules — with comments on which values are safe and which change the cost profile.
  • Flow schemes: the path of a request from queueing to network confirmation, and the points where fee recalculation and resend are triggered.
  • Threshold and trigger descriptions: under what conditions the system raises the fee, when it lowers it, what counts as an emergency deviation, and how it is signaled.
  • Access rules: roles, who may change thresholds in production, who can only read metrics, and the change approval procedure.
  • Monitoring dashboards: share of confirmed transactions, average cost, time to confirmation, number of replacements — with an explanation of how to read the charts and where to look for the cause of a deviation.
  • Maintenance procedure: frequency of threshold review, configuration update procedure, and rollback plan to the previous set of parameters.
  • Incident instructions: typical failures, step-by-step check sequence, and escalation conditions to us.
  • Acceptance protocols: control scenarios and before-and-after measurements after enabling optimization.

Case study: reducing execution costs of operations

The project is a recurring settlement service: several thousand operations per day, each reads contract state and writes the result to a contract on Ethereum.

The execution price was calculated using a single static "buffer" multiplier: during peak hours transactions hung, the price was raised manually, overpayment reached up to 40% of the estimated amount, and the failure rate stayed at 9–12%.

What was rebuilt

We moved away from manual control.

The base fee forecast is built from the dynamics of recent blocks; on delay, a retry is sent with step-by-step price increases until confirmation; the limit is calculated from the actual consumption of similar operations, not from a round buffer number.

The state access scheme was completely rewritten: values read multiple times within a single call are cached in memory, four storage writes are collapsed into one, and identical operations are assembled into a batch call instead of dozens of separate transactions.

Result

Overpayment relative to the estimated price fell from 38–40% to 5–7%, the failure rate from 9–12% to less than 1%, the number of state accesses per operation decreased by three times, and the cost of a typical operation by 2.4 times.

Implementation took six weeks: first price forecasting and resend, then batch processing, and finally storage restructuring. The old and new paths ran in parallel, switching was done with one setting, so rollback to the previous scheme took minutes.

How does batch sending differ from single calls?

A single call is one operation in one transaction: its own signature, its own gas limit, its own result. Batch sending combines several identical operations into one contract call: the base part of gas is paid once, and the variable part grows only with execution. The gain is noticeable where operations are mass-scale and identical in structure.

The approaches differ in resilience to peaks. Single calls are sensitive to a fee spike: the signature queue falls apart, some transactions hang and require manual review. A batch is assembled once, but requires a gas limit buffer — otherwise it fails entirely, not partially.

The rollback logic also differs. Single mode provides targeted rollback: we repeat only the failed operation.

A batch is atomic, so duplicate checks, a batch size limit, and a clear failure reason are built into the contract, while the service handles reassembly from failed elements.

Criterion Batch sending Single calls
Resilience to peaks one assembly, gas buffer needed signature queue breaks
Rollback logic atomic, entire batch targeted, per operation
Contract requirements loop, limits, duplicate protection one function per operation
Maintenance failure analysis is harder more transactions in monitoring

In practice, a hybrid is more often used: mass identical operations go in batches, while heterogeneous ones go as single calls. The choice is determined by the load profile, not by the size of the gain on a single call.

Technical limitations and common client questions

Gas optimization almost never means "rewriting everything from scratch." Existing contracts are immutable, so we change not the code but the call scheme: batch sending of operations, the order of state writes, elimination of intermediate saves, and moving computations outside the verified part.

Sometimes it is cheaper to add a new layer alongside than to touch a proven contract — this is the main limitation of the scheme, and it is where we begin the analysis.

We record the effect with before-and-after measurements on a copy of the network: how many execution operations are required per business operation, what share of transactions fail due to insufficient limit, and how confirmation time changes under load.

Without measurements, optimization turns into guesswork, and integration risk turns into unpredictability for wallets and internal services.

We already have contracts in production — will they have to be rewritten?

No, and most often it is impossible: a deployed contract does not change. We work with what surrounds it — redistribute logic between calls, combine operations into one transaction, and remove unnecessary state writes. We connect new code as a separate layer and gradually migrate the stream to it.

What about integrations — wallets, exchanges, internal services?

External interfaces must remain the same: the same methods, the same events, the same response format. If a call signature changes, all counterparties will have to update it simultaneously — this is a separate risk that we assess before work begins and avoid where possible.

How do you prove that things got better?

With measurements on a copy of the network using a real load profile: the share of execution operations per business operation, the number of failures due to insufficient limit, and confirmation time.

The before-and-after comparison uses the same set of scenarios, and we roll out changes so that it is possible to return to the previous scheme.

Let's discuss the task: where work begins

We start with an analysis of the source data, not with general promises: without real gas consumption figures, any project estimate remains a guess. The more specific the inputs, the more accurately we can state the timeline and scope of work.

What to send for an initial analysis:

  • contract addresses and their purpose: transfers, swaps, token issuance, settlement calls;
  • 5–10 hashes of real transactions from different scenarios — they show exactly where gas goes;
  • approximate volumes: how many operations occur per day and how many during peak hours;
  • current consumption metrics: average and maximum gas per operation;
  • contract interaction schemes, if the logic is distributed across several contracts;
  • requirements for confirmation latency and operation processing order;
  • limitations: network, available tooling, and what cannot be changed in contract logic.

Next, we will break down the calls by execution cost and note which changes deliver an effect immediately and which require reworking the logic.

As a result, we will come back with a project estimate and work plan: stages, what is needed from your side at each, and target gas reduction metrics — we verify them on a test network before rolling out to the main one.

Let's discuss the task: describe it in a message, and we will gather the missing data together with your engineers.