<p>there are two options that do come to my mind to calculate a transaction size:</p>
<h2>starting from the fees</h2>
<p>since we know that the fees are calulated as <code>a * size(tx) + b == fees</code>
using some simple algebra we can see that <code>size(tx) == (fees - b) / a</code></p>
<p>this should be the most reliable way, but you need the fees in order to calculate the size, so it shouldn't fit you request</p>
<h2>use the CBOR size</h2>
<p>when builing a transaction using either <code>cardano-cli transaction build</code> or <code>cardano-cli transaction build-raw</code> you need to specify an <code>--out-file</code> which turns out to be a <code>.json</code> file with the following chema:</p>
<pre><code>{
    &quot;type&quot;: &quot;Tx AlonzoEra&quot;,
    &quot;description&quot;: &quot;&quot;,
    &quot;cborHex&quot;: &quot;&lt;some hex value&gt;&quot;
}
</code></pre>
<p>ultimately the <code>cborHex</code> value is what goes on-chain
that value is an hexadecimal string and represents the bytes of the CBOR message</p>
<p>since we know that each byte can have a value from <code>0</code> to <code>255</code> the hex representation must take 2 hexadecimal digits per byte</p>
<p>this way you could calculate the tx size in bytes as half the length of the cborHex string</p>
<p>in nodejs</p>
<pre><code>&quot;&lt;some hex value&gt;&quot;.length / 2
</code></pre>
<p>however, this approach returns usually a value smaller by ~400/~500 bytes in contrast to the first approach, so I might be missing some data</p>
<h4>P.S. <code>cardano-serialization-library</code></h4>
<p>using the <code>cardano-serialization-library</code> it should be enough to use the <code>Transaction.to_bytes()</code> method and get the length</p>
<p>e.g.</p>
<pre><code>myTx.to_bytes().length
</code></pre>

CC BY-SA 4.0
2022-06-19T11:46:02.650Z
2022-06-19T11:46:02.650Z
Michele Nuzzi
<p>Here is my bash script</p>
<pre><code>fee=$(cardano-cli transaction calculate-min-fee \
                    --tx-body-file tx.tmp \
                    --tx-in-count 1 \
                    --tx-out-count 1 \
                    --mainnet \
                    --witness-count 1 \
                    --byron-witness-count 0 \
                    --protocol-params-file protocol.json | awk '{ print $1 }') &gt;&gt; $log
</code></pre>
<p>In your case, it depends how many TX_in and TX_outs you will have.</p>

CC BY-SA 4.0
2022-01-26T06:25:52.260Z
tx.tmp will create it by :

cardano-cli transaction build-raw \
                    --fee 200000 \
                    --tx-in ${tx_in} \
                    --tx-out ${in_addr}+${utxo_balance} \
                    --invalid-hereafter $(( ${currentSlot} + 2000)) \
                    --out-file tx.tmp >> $log
TTS17
CC BY-SA 4.0
2022-01-26T06:20:09.083Z
2022-01-26T22:56:28.613Z
2022-01-26T22:56:28.613Z
TTS17
<p>The <code>a</code> and <code>b</code> fees parameters are protocol parameters, so you should probably check the current epoch, even they are unlikely to change suddenly.</p>
<pre><code>$ curl -s  -H &quot;project_id: $BLOCKFROST_PROJECT_ID&quot; https://cardano-mainnet.blockfrost.io/api/v0/epochs/latest/parameters | jq '. | .min_fee_a, .min_fee_b'
44
155381
</code></pre>
<p>Then, all your need to do to calculate your fees is:</p>
<pre><code>a × size (in bytes) + b
</code></pre>
<p>Read more on <a href="https://docs.cardano.org/explore-cardano/fee-structure" rel="nofollow noreferrer">docs.cardano.org</a>.</p>

CC BY-SA 4.0
2021-08-30T20:04:14.327Z
To get the exact size in bytes, you're going to want to build the transaction and include a dummy value for the fee even though you don't know it yet. Then you can get the exact number of bytes the transaction will take instead of doing estimates based on UTxO counts and such. Then, just calculate as @Marek showed and re-build the Tx a second time with the exact fees.
Andrew Westberg - BCSH
CC BY-SA 4.0
2021-08-30T23:18:51.907Z
Thanks, you've both been helpful. I guess I probably also wasn't perfectly clear. I'm trying to figure out how to get the `size(tx)` value. I was wandering if I could do it without the CLI? I'm assuming its not the size of the ASCII characters in bytes but formatted differently. I couldn't find the exact info in the docs (although I'm sure its there somewhere).
nalyd88
CC BY-SA 4.0
2021-08-31T02:41:35.320Z
Thanks Marek, I forgot to check the protocol parameters file. I was looking in the genesis files but of course it can change!
nalyd88
CC BY-SA 4.0
2021-09-22T12:55:56.813Z
@nalyd88 The only way to get the size of the transaction without using cardano-cli is to build the cbor for everything yourself. I do this with my firehose project, but it's quite involved. Even cardano-cli doesn't give you exactly the minfee value. It just does a best guess estimate and pads it a bit. Things like stake vs enterprise output addresses can change the size of cbor and affect fees.
Andrew Westberg - BCSH
CC BY-SA 4.0
2021-08-30T13:25:00.227Z
2022-04-06T23:31:43.720Z
2022-04-06T23:31:43.720Z
Marek Mahut - StakeNuts
<p>The correct formula for <strong>non-smart contract transactions</strong> is indeed still <code>a*size(tx) + b</code>, with <code>a=44</code> and <code>b=155381</code>.</p>
<p><code>size(tx)</code> is calculated as the number of bytes of the CBOR encoding of the transaction, which can differ per era. For example Babbage introduced a new way of encoding transaction outputs, which results in slightly larger transactions. The old way of encoding transaction outputs is however still permitted because it is a bit smaller, so <code>size(tx)</code> can differ depending on what tool/wallet created the transaction.</p>
<h4>cardano-cli</h4>
<p>Getting exactly the same result as <em>cardano-cli</em> is sadly not straightforward because it has a few quirks:</p>
<ul>
<li>the <code>isValid</code> byte is omitted when calculating <code>size(tx)</code> (which IOG claims is to stay consistent with the Mary era)</li>
<li>if the fee is being calculated during <em>tx building</em>, then for each regular input, collateral input, required native script signature, and plutus script signature, a dummy pub key and signature is added (96 bytes + encoding overhead). This is usually an overestimation because many of the required signatures will be the same.</li>
</ul>
<p>You can quite easily calculate the max number of potential signatures, but the CBOR encoding overhead is difficult to estimate manually (I don't recommend you even try without an appropriate library/framework):</p>
<pre><code>size(tx) = size(tx_without_signatures) 
         + num_signatures*(96 + cbor_overhead_per_signature) 
         + cbor_overhead_for_all_signatures 
         - 1
</code></pre>
<p>If the estimated number of signatures equals the actual number of signatures, and you used the actual on-chain size of the transaction as <code>size(tx)</code>, you will probably just be off by 1 byte, i.e. <code>44</code> lovelace difference wrt. the <em>cardano-cli</em> result.</p>
<p><em>Disclaimer: this is how cardano-cli works internally as far as I'm currently aware, but this is subject to change (e.g. a more accurate estimation of the number of signatures is marked as <code>TODO</code> in the IOG codebase).</em></p>
<h4>smart contract transactions</h4>
<p>For completeness I'll mention that Alonzo introduced an additional fee to take into account <strong>validator execution</strong>, and Conway will introduce another additional fee for the <strong>size of reference scripts</strong>.</p>
<p>Estimating validator execution budgets is entirely unpractical when done manually, so for any transactions involving smart contracts you need to use a framework (CSL, Aiken, Helios etc.)</p>

CC BY-SA 4.0
2024-04-14T05:22:12.963Z
2024-04-14T05:30:44.237Z
2024-04-14T05:30:44.237Z
Christian Schmitz
<p>I realize that the CLI has commands for calculating a minimum fee based on a transaction size, but I'm wanting to do a calculation manually. The documentation states that the formula for calculating the transaction minimum fee is <code>a * size(tx) + b</code> where <code>a</code> &amp; <code>b</code> are protocol parameters, and <code>size(tx)</code> is the transaction size in bytes.</p>
<p>Is there a way to calculate the transaction size if I know the number of consumed and output UTxOs? Also, are <code>a</code> and <code>b</code> in the genesis file?</p>

<transaction>
Manual Calculation of Transaction Size and Fee
# Manual Calculation of Transaction Size and Fee

(Asked by: username_0 on 2021-08-30)

I realize that the CLI has commands for calculating a minimum fee based on a transaction size, but I'm wanting to do a calculation manually. The documentation states that the formula for calculating the transaction minimum fee is `a * size(tx) + b` where `a` & `b` are protocol parameters, and `size(tx)` is the transaction size in bytes.

Is there a way to calculate the transaction size if I know the number of consumed and output UTxOs? Also, are `a` and `b` in the genesis file?

**Tags:** transaction

---

## 4 answers

### Answer by username_1 on 2022-06-19. Score: 3

there are two options that do come to my mind to calculate a transaction size:
starting from the fees
since we know that the fees are calulated as a * size(tx) + b == fees
using some simple algebra we can see that size(tx) == (fees - b) / a
this should be the most reliable way, but you need the fees in order to calculate the size, so it shouldn't fit you request
use the CBOR size
when builing a transaction using either cardano-cli transaction build or cardano-cli transaction build-raw you need to specify an --out-file which turns out to be a .json file with the following chema:
{
    "type": "Tx AlonzoEra",
    "description": "",
    "cborHex": ""
}

ultimately the cborHex value is what goes on-chain
that value is an hexadecimal string and represents the bytes of the CBOR message
since we know that each byte can have a value from 0 to 255 the hex representation must take 2 hexadecimal digits per byte
this way you could calculate the tx size in bytes as half the length of the cborHex string
in nodejs
"".length / 2

however, this approach returns usually a value smaller by ~400/~500 bytes in contrast to the first approach, so I might be missing some data
P.S. cardano-serialization-library
using the cardano-serialization-library it should be enough to use the Transaction.to_bytes() method and get the length
e.g.
myTx.to_bytes().length


---

### Answer by username_2 on 2022-01-26. Score: 2

Here is my bash script
fee=$(cardano-cli transaction calculate-min-fee \
                    --tx-body-file tx.tmp \
                    --tx-in-count 1 \
                    --tx-out-count 1 \
                    --mainnet \
                    --witness-count 1 \
                    --byron-witness-count 0 \
                    --protocol-params-file protocol.json | awk '{ print $1 }') >> $log

In your case, it depends how many TX_in and TX_outs you will have.

> **Comments:**
> **username_2**: tx.tmp will create it by :  cardano-cli transaction build-raw \                     --fee 200000 \                     --tx-in ${tx_in} \                     --tx-out ${in_addr}+${utxo_balance} \                     --invalid-hereafter $(( ${currentSlot} + 2000)) \                     --out-file tx.tmp >> $log  

---

### Answer by username_3 on 2021-08-30. Score: 2

The a and b fees parameters are protocol parameters, so you should probably check the current epoch, even they are unlikely to change suddenly.
$ curl -s  -H "project_id: $BLOCKFROST_PROJECT_ID" https://cardano-mainnet.blockfrost.io/api/v0/epochs/latest/parameters | jq '. | .min_fee_a, .min_fee_b'
44
155381

Then, all your need to do to calculate your fees is:
a × size (in bytes) + b

Read more on docs.cardano.org.

> **Comments:**
> **username_4**: To get the exact size in bytes, you're going to want to build the transaction and include a dummy value for the fee even though you don't know it yet. Then you can get the exact number of bytes the transaction will take instead of doing estimates based on UTxO counts and such. Then, just calculate as @Marek showed and re-build the Tx a second time with the exact fees.  
> **username_0**: Thanks, you've both been helpful. I guess I probably also wasn't perfectly clear. I'm trying to figure out how to get the `size(tx)` value. I was wandering if I could do it without the CLI? I'm assuming its not the size of the ASCII characters in bytes but formatted differently. I couldn't find the exact info in the docs (although I'm sure its there somewhere).  
> **username_0**: Thanks Marek, I forgot to check the protocol parameters file. I was looking in the genesis files but of course it can change!  
> **username_4**: @nalyd88 The only way to get the size of the transaction without using cardano-cli is to build the cbor for everything yourself. I do this with my firehose project, but it's quite involved. Even cardano-cli doesn't give you exactly the minfee value. It just does a best guess estimate and pads it a bit. Things like stake vs enterprise output addresses can change the size of cbor and affect fees.  

---

### Answer by username_5 on 2024-04-14. Score: 1

The correct formula for non-smart contract transactions is indeed still a*size(tx) + b, with a=44 and b=155381.
size(tx) is calculated as the number of bytes of the CBOR encoding of the transaction, which can differ per era. For example Babbage introduced a new way of encoding transaction outputs, which results in slightly larger transactions. The old way of encoding transaction outputs is however still permitted because it is a bit smaller, so size(tx) can differ depending on what tool/wallet created the transaction.
cardano-cli
Getting exactly the same result as cardano-cli is sadly not straightforward because it has a few quirks:

the isValid byte is omitted when calculating size(tx) (which IOG claims is to stay consistent with the Mary era)
if the fee is being calculated during tx building, then for each regular input, collateral input, required native script signature, and plutus script signature, a dummy pub key and signature is added (96 bytes + encoding overhead). This is usually an overestimation because many of the required signatures will be the same.

You can quite easily calculate the max number of potential signatures, but the CBOR encoding overhead is difficult to estimate manually (I don't recommend you even try without an appropriate library/framework):
size(tx) = size(tx_without_signatures) 
         + num_signatures*(96 + cbor_overhead_per_signature) 
         + cbor_overhead_for_all_signatures 
         - 1

If the estimated number of signatures equals the actual number of signatures, and you used the actual on-chain size of the transaction as size(tx), you will probably just be off by 1 byte, i.e. 44 lovelace difference wrt. the cardano-cli result.
Disclaimer: this is how cardano-cli works internally as far as I'm currently aware, but this is subject to change (e.g. a more accurate estimation of the number of signatures is marked as TODO in the IOG codebase).
smart contract transactions
For completeness I'll mention that Alonzo introduced an additional fee to take into account validator execution, and Conway will introduce another additional fee for the size of reference scripts.
Estimating validator execution budgets is entirely unpractical when done manually, so for any transactions involving smart contracts you need to use a framework (CSL, Aiken, Helios etc.)


---

