# Fees in StarkNet Alpha

**URL:** <https://community.starknet.io/t/fees-in-starknet-alpha/286>\
**Category:** Starknet Technical Development\
**Tags:** fees, alpha\
**Created:** [January 3, 2022, 2:10pm UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286 "2022-01-03T14:10:13Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![lior-stark](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/lior-stark/32/14_2.png) [@lior-stark](https://community.starknet.io/u/lior-stark)\
**Post date:** [January 3, 2022, 2:10pm UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/1 "2022-01-03T14:10:13Z")

</div>

StarkNet Alpha launched on Mainnet a few weeks ago, without a transaction fee mechanism, i.e., with L1 gas costs effectively subsidized by StarkWare. We present a method to estimate and collect transaction fees in the current StarkNet Alpha version.

As the network evolves, we expect the way fees are evaluated and collected to evolve as well. We present here a first approximation of calculation and method for collecting fees, with the purpose of refining it as StarkNet evolves. Knowing these parameters will help builders to better plan when designing their StarkNet dApp.

# Transaction Cost in StarkNet

Generally, a transaction’s cost depends on several factors:

1. Data - the amount of data sent to L1:  
1.1 State diff information  
1.2 Number of L2 → L1 messages  
1.3 The L1 → L2 messages that were consumed  
These are sent as call data to L1 in different StarkNet L1 transactions.
2. Cost of computation - this is the count of trace steps, including the OS steps, i.e., system calls.  
It includes:
  1. L1 proof verification
  2. L2 computation cost (SHARP)

3. Storage cost: how many read/write operations were performed during the transaction execution.
4. L2 network transmission cost for the transaction: its call data and events emitted.

# Current Mechanism

At a high level, the current solution lets users/applications use the sequencer to get an estimate for the fee required to accept the transaction:

 ![fees](https://europe1.discourse-cdn.com/flex005/uploads/starknet1/original/1X/1df8c08d08b408df2faab1803ccb4c10afd4e045.jpeg)

A user asks a new service (”estimate gas service”) to estimate the fee required to run the given transaction at the current state. The service estimates and returns the result based on the formula below. This service is exposed by the sequencer. Internally, it will try to estimate the resources consumed by processing the transaction based on the current StarkNet state.

As explained below, the estimation will be a first and somewhat rough approximation of the transaction cost. The fee itself will be specified in ETH - the payment currency - with the gas price provided as a parameter of the estimated service.

At this point, the user can choose whether to accept the estimated fee or mark it up/down. The user then signs the fee she’s willing to pay, as part of the transaction and sends it to the sequencer to be executed and added to a future block.

## The Cost Formula

Our first approximation for the fee considers some of the external costs that the service provider (sequencer+prover) pays, like L1 gas for data and computation (items 1 and 2.1 above). The fee calculated may include a markup to compensate for L1 gas cost fluctuations.  
At this point, we neglect L2 costs for proof creation, storage operations, and network (items 2.2, 3, 4 above).

The formula, therefore, for calculating the cost, at this phase, will be:

\begin{aligned} gas\_price \cdot &( \\ \sharp(msgs) \cdot &5 \cdot 10^3 \\ + gas\_&per\_byte \cdot ( \\ &\sharp(msgs) \cdot bytes\_per\_msg \\ &+ \sharp(state\_diff\_items) \cdot 2 \cdot 31 ) \\ + gas\_per&\_step \cdot steps\_{txn} ) \end{aligned}

where:

1. gas\_price is the gas price, ETH per gas unit, configured in the service.  
This may be later exposed for querying through an API.
2. gas\_per\_byte is the gas cost of storing a single byte as call data, currently 16 gas per byte.
3. \sharp(msgs) is the number of messages sent by the transaction from L2 to L1.
4. bytes\_per\_msg is the number of bytes of the message. This could of course be different per message, so we may use an average message size for all messages.  
The 5000 extra gas is for updating an internal counter.
5. \sharp(state\_diff\_items) is the number of state diffs done by this transaction.  
The 2 \cdot 31 factor comes from writing two field elements per storage write, each field element consisting of 31 bytes.
6. gas\_per\_step is a constant pricing for a single step validation (on L1).  
steps\_{txn} is the number of steps for this function’s execution.

> ❗ The main factor driving the cost is the L1 data component. This includes the state diff and the messages. In other words, the computation cost will be negligible compared to the cost of data posted on L1 (gas\_per\_step \<\< gas\_per\_byte).

# The Road Ahead

We see several possible ways this mechanism might change in the future.

First, we expect to make several optimizations that will reduce the cost. Specifically, when several transactions share the same proof, they share some overhead and therefore might cost less to produce and verify. In such a case, some reduction may be applied to the fees estimated for the original transactions.

Introducing volition for data availability (i.e. off-chain data availability) should provide another opportunity for cost savings, and we expect we will be able to factor it into the cost estimation. Storage modifications done for L2-based data may bear different costs.

When the network becomes decentralized, we expect other mechanisms and market designs to apply, the details of which are currently being researched. An example would be to make fee auction possible - users will specify the fee as some linear combination of the different cost components, and allow the sequencer to pick the transaction with the most beneficial fee.

Finally, introducing fee abstraction will allow network participants to specify fees in tokens other than ETH.

---

<div class="post-metadata">

**Author:** ![Orland0x](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/orland0x/32/166_2.png) [@Orland0x](https://community.starknet.io/u/Orland0x)\
**Post date:** [January 3, 2022, 3:49pm UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/2 "2022-01-03T15:49:48Z")

</div>

Do you have any idea on the size that the markup would need to be to compensate for fluctuations? I was just thinking another option could be to forecast the gas cost at the time the batch will be submitted to L1, this way one might be able to get away with a small markup or none at all.

---

<div class="post-metadata">

**Author:** ![zigzagdev](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/zigzagdev/32/32_2.png) [@zigzagdev](https://community.starknet.io/u/zigzagdev)\
**Post date:** [January 3, 2022, 4:57pm UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/3 "2022-01-03T16:57:21Z")

</div>

Is 5000 going to be a minimum gas consumed by every transaction on Starknet?

---

<div class="post-metadata">

**Author:** ![fracek](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/fracek/32/23_2.png) [@fracek](https://community.starknet.io/u/fracek)\
**Post date:** [January 3, 2022, 5:15pm UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/4 "2022-01-03T17:15:38Z")

</div>

> [@lior-stark](#):
>
> ♯(state\_diff\_items) is the number of state diffs done by this transaction.  
> The 2⋅312 \cdot 312⋅31 factor comes from writing two field elements per storage write, each field element consisting of 31 bytes.

A common pattern in Solidity is to `del` memory that’s not used anymore to save user’s gas. I guess on StarkNet that’s not the case and so it will be cheaper to have our smart contracts use a `deleted` flag over zeroing the old values we want to delete?

---

<div class="post-metadata">

**Author:** ![Genysys](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/genysys/32/168_2.png) [@Genysys](https://community.starknet.io/u/Genysys)\
**Post date:** [January 3, 2022, 6:15pm UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/5 "2022-01-03T18:15:54Z")

</div>

Thanks for this , a couple of questions

- Estimate Gas Service: This introduces a point of centralisation to the StarkNet system. Would be it possible to open it up to third party services to observe it?
- Implementation: I think it would be best to incentivise Wallet providers to handle fee estimation, similar to how it works on Etherum.
- Currency: What currency would the fee be payable in?

---

<div class="post-metadata">

**Author:** ![RoboTeddy](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/roboteddy/32/114_2.png) [@RoboTeddy](https://community.starknet.io/u/RoboTeddy)\
**Post date:** [January 3, 2022, 7:43pm UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/6 "2022-01-03T19:43:16Z")

</div>

I think the `5000` referenced in the original post is just an extra gas cost per L2-\>L1 message, so it probably won’t apply to starknet tx that aren’t sending messages over the bridge.

---

<div class="post-metadata">

**Author:** ![xJonathanLEI](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/xjonathanlei/32/93_2.png) [@xJonathanLEI](https://community.starknet.io/u/xJonathanLEI)\
**Post date:** [January 4, 2022, 2:23am UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/7 "2022-01-04T02:23:30Z")

</div>

Nice post, thanks! My questions:

- One of the most quoted benefits of StarkNet is the state diff aggregation: only 1 state diff needs to be sent on L1 per batch for the same storage slot no matter how many intermediate changes happened on L2. This batch-wide cost saving is not passed onto users under the current model.

- How do you determine fee payer? Is it the contract being invoked? What if it’s a contract deployment transaction?

---

<div class="post-metadata">

**Author:** ![lior-stark](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/lior-stark/32/14_2.png) [@lior-stark](https://community.starknet.io/u/lior-stark)\
**Post date:** [January 4, 2022, 7:16am UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/8 "2022-01-04T07:16:02Z")

</div>

> [@Orland0x](#):
>
> I was just thinking another option could be to forecast the gas cost at the time the batch will be submitted to L1, this way one might be able to get away with a small markup or none at all.

That’s one possibility.  
At this point though we’ll start with something simpler that will allow us to get going, and set it manually.

---

<div class="post-metadata">

**Author:** ![lior-stark](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/lior-stark/32/14_2.png) [@lior-stark](https://community.starknet.io/u/lior-stark)\
**Post date:** [January 4, 2022, 7:17am UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/9 "2022-01-04T07:17:22Z")

</div>

> [@zigzagdev](#):
>
> Is 5000 going to be a minimum gas consumed by every transaction on Starknet?

No. The 5000 that appears there is per message sent to L1.  
If your transaction doesn’t send messages, this shouldn’t come into the estimate.

---

<div class="post-metadata">

**Author:** ![lior-stark](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/lior-stark/32/14_2.png) [@lior-stark](https://community.starknet.io/u/lior-stark)\
**Post date:** [January 4, 2022, 7:21am UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/10 "2022-01-04T07:21:08Z")

</div>

> [@fracek](#):
>
> A common pattern in Solidity is to `del` memory that’s not used anymore to save user’s gas. I guess on StarkNet that’s not the case and so it will be cheaper to have our smart contracts use a `deleted` flag over zeroing the old values we want to delete?

We’re still looking into how data will be managed in general, and how we’ll ensure availability.  
And the cost of data managed will likely take this into consideration (e.g. if there’s volition on how to manage the data).

I’m not entirely sure I follow your suggestion on the `deleted` flag. Do you mean to somehow mark a specific storage variable as deleted? or something else?

---

<div class="post-metadata">

**Author:** ![lior-stark](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/lior-stark/32/14_2.png) [@lior-stark](https://community.starknet.io/u/lior-stark)\
**Post date:** [January 4, 2022, 7:29am UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/11 "2022-01-04T07:29:27Z")

</div>

> [@Genysys](#):
>
> Estimate Gas Service: This introduces a point of centralisation to the StarkNet system. Would be it possible to open it up to third party services to observe it?

Right, but note this is for the current Alpha release, which still relies on a central sequencer.

I don’t see a fundamental issue with other providers having a similar functionality; but for the estimation to be good enough, you’d have to rely on the current state.

* * *

> [@Genysys](#):
>
> What currency would the fee be payable in

For now ETH.

---

<div class="post-metadata">

**Author:** ![lior-stark](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/lior-stark/32/14_2.png) [@lior-stark](https://community.starknet.io/u/lior-stark)\
**Post date:** [January 4, 2022, 9:31am UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/12 "2022-01-04T09:31:06Z")

</div>

> [@xJonathanLEI](#):
>
> One of the most quoted benefits of StarkNet is the state diff aggregation: only 1 state diff needs to be sent on L1 per batch for the same storage slot no matter how many intermediate changes happened on L2. This batch-wide cost saving is not passed onto users under the current model.

Indeed, that’s the optimization mentioned as an example of one way to evolve this.

* * *

> [@xJonathanLEI](#):
>
> How do you determine fee payer? Is it the contract being invoked?

We plan on using some form of [account abstraction](https://www.starknet.io/blog/account-abstraction/), so transaction invocation will go through account contracts (“wallet contracts”). The details are still being debated.  
As for deployment, this is indeed an open point we’ll need to address.

---

<div class="post-metadata">

**Author:** ![fracek](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/fracek/32/23_2.png) [@fracek](https://community.starknet.io/u/fracek)\
**Post date:** [January 4, 2022, 10:50am UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/13 "2022-01-04T10:50:48Z")

</div>

> [@lior-stark](#):
>
> I’m not entirely sure I follow your suggestion on the `deleted` flag. Do you mean to somehow mark a specific storage variable as deleted? or something else?

For example if I store a list of elements I will have two storage variables: one with the number of elements in the list, the other (indexed by index) with the actual elements. If I want to delete the list I just set the length to 0 without zeroing each individual element. In solidity I would `del` the second mapping (the one with elements) to save some gas to the user.

---

<div class="post-metadata">

**Author:** ![lior-stark](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/lior-stark/32/14_2.png) [@lior-stark](https://community.starknet.io/u/lior-stark)\
**Post date:** [January 4, 2022, 10:59am UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/14 "2022-01-04T10:59:53Z")

</div>

@fracek  
Ok, I see now.  
At this point yes, it would probably be cheaper to use such a flag.

---

<div class="post-metadata">

**Author:** ![maciejka](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/maciejka/32/96_2.png) [@maciejka](https://community.starknet.io/u/maciejka)\
**Post date:** [January 4, 2022, 1:56pm UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/15 "2022-01-04T13:56:24Z")

</div>

> [@lior-stark](#):
>
> The formula, therefore, for calculating the cost, at this phase, will be:
> 
> gas\_price⋅(gas\_per\_byte⋅(♯(msgs)⋅(bytes\_per\_msg+5⋅103)+♯(state\_diff\_items)⋅2⋅31)+gas\_per\_step⋅stepstxn) \begin{aligned} gas\_price \cdot &( \ gas\_per\_&byte \cdot ( \ &\sharp(msgs) \cdot (bytes\_per\_msg + 5 \cdot 10^3) \ &+ \sharp(state\_diff\_items) \cdot 2 \cdot 31 ) \ + gas\_per&\_step \cdot steps\_{txn} ) \end{aligned} gas\_price⋅gas\_per\_+gas\_per​(byte⋅(♯(msgs)⋅(bytes\_per\_msg+5⋅103)+♯(state\_diff\_items)⋅2⋅31)\_step⋅stepstxn​)​

Units does not match: 5\*10^3 seems to be in gas units while it is added to `bytes_per_msg` which is in bytes.

---

<div class="post-metadata">

**Author:** ![FeedTheFed](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/feedthefed/32/72981_2.png) [@FeedTheFed](https://community.starknet.io/u/FeedTheFed)\
**Post date:** [January 4, 2022, 2:11pm UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/16 "2022-01-04T14:11:24Z")

</div>

Correct, editing (need more characters)

---

<div class="post-metadata">

**Author:** ![lior-stark](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/lior-stark/32/14_2.png) [@lior-stark](https://community.starknet.io/u/lior-stark)\
**Post date:** [January 4, 2022, 3:12pm UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/17 "2022-01-04T15:12:15Z")

</div>

> [@maciejka](#):
>
> Units does not match:

Right. Thanks for bringing it up.

---

<div class="post-metadata">

**Author:** ![bbrandtom](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/bbrandtom/32/9_2.png) [@bbrandtom](https://community.starknet.io/u/bbrandtom)\
**Post date:** [January 5, 2022, 7:18am UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/18 "2022-01-05T07:18:19Z")

</div>

> [@Genysys](#):
>
> - Estimate Gas Service: This introduces a point of centralisation to the StarkNet system. Would be it possible to open it up to third party services to observe it?
> - Implementation: I think it would be best to incentivise Wallet providers to handle fee estimation, similar to how it works on Etherum.

That’s a good point. The problem is that currently we don’t have full nodes available for anyone to run. The current solution is a way to bridge the gap and is temporary. This is a good point and we should probably mention it explicitly in the post.

The first version of pathfinder (rust full node) is aimed for the end of the month. Many API services will start integrating it once it’s out. This will allow us to change the flow and to estimate gas locally or through the API services, by executing the transaction in the full node.

---

<div class="post-metadata">

**Author:** ![seanchung](https://avatars.discourse-cdn.com/v4/letter/s/f08c70/32.png) [@seanchung](https://community.starknet.io/u/seanchung)\
**Post date:** [January 5, 2022, 4:02pm UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/19 "2022-01-05T16:02:03Z")

</div>

Well done. Progress everyday.

---

<div class="post-metadata">

**Author:** ![martriay](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/martriay/32/25_2.png) [@martriay](https://community.starknet.io/u/martriay)\
**Post date:** [January 6, 2022, 3:55am UTC](https://community.starknet.io/t/fees-in-starknet-alpha/286/20 "2022-01-06T03:55:35Z")

</div>

Great progress! I’d like to second the concerns around gas estimation services since any downtime could really harm the network.

> [@lior-stark](#):
>
> This could of course be different per message, so we may use an average message size for all messages.

why an average instead of dynamic for each message?

> [@lior-stark](#):
>
> ♯(state\_diff\_items) is the number of state diffs done by this transaction.

do you mean the number of state updates or the size of the state diff?

> [@lior-stark](#):
>
> An example would be to make fee auction possible - users will specify the fee as some linear combination of the different cost components, and allow the sequencer to pick the transaction with the most beneficial fee.

does this mean that the current tx ordering is still FIFO? so MEV is going to be a latency game more than anything. Have you looked into [proposer-builder separation](https://ethresear.ch/t/proposer-block-builder-separation-friendly-fee-market-designs/9725)? do you think that would make any sense in here?

[Next page](https://community.starknet.io/t/fees-in-starknet-alpha/286.md?page=2)
