PostsZK + PARTH Bonus: How Many Concurrent Users does Psy need to hit 100,000 TPS

ZK + PARTH Bonus: How Many Concurrent Users does Psy need to hit 100,000 TPS

5 min read
by Carter Jack Feldman

In this post, we will derive a formula which calculates the number of users that need to participate in a Psy block to attain 100,000 TPS.

In our previous blog post, we showed that the TPS of Psy running on a 2-to-1 configuration can be calculated as:

TPS(u)=# of TransactionsBlock Time=ktx∗ulog⁡4(u)∗(kr+knet)TPS(u)=\frac{\text{\# of Transactions}}{\text{Block Time}}=\frac{k_{\text{tx}}*u}{\log_4(u)*(k_r+k_{net})} local-proving-time-revised-outlined.png

In reality, Psy uses a 4-to-1 proof configuration, where each decentralized proving job recursively verifiers 4 proofs and 4 delta merkle proofs for performance reasons, so the actual equation we can use to model our TPS is:

TPS(u)=# of TransactionsBlock Time=ktx∗ulog⁡4(u)∗(kr+knet)TPS(u)=\frac{\text{\# of Transactions}}{\text{Block Time}}=\frac{k_{\text{tx}}*u}{\log_4(u)*(k_r+k_{net})}

Where:

  • uu is the number of users participating in a block

  • ktxk_{tx} is the average number of transactions each participating user performs during the block

  • krk_r is the time it takes to recursively verify 2 proofs and associated delta merkle proofs (proving time for each job performed by the decentralized proving network)

  • knetk_{net} is the time it takes to send a proof to a decentralized proof miner (~30kb)

The only downside of using a 4-to-1 configuration is that our proving time is slightly longer, notably ~500ms on consumer hardware instead of 380ms in the 2-to-1 configuration.

Calculating the numbers user required to hit 100,000 TPS

Using our formula, if we wanted to see how many users would need to participate in a block to attain a TPS of 100,000, we would need to solve the equation below for uu:

100000=ktx∗ulog⁡4(u)∗(kr+knet)100000=\frac{k_{\text{tx}}*u}{\log_4(u)*(k_r+k_{net})}

To find the inverse, let's first clean up our equation a bit, we will say xx represents our desired TPS:

t=ktx∗ulog⁡4(u)∗(kr+knet)t=\frac{k_{\text{tx}}*u}{\log_4(u)*(k_r+k_{net})}

Let's clean things up a bit, substituting log⁡4(u)=ln⁡(u)ln⁡(4)\log_4(u)=\frac{\ln(u)}{\ln(4)} using the change of base rule for logarithms:

t=ktx∗ulog⁡4(u)∗(kr+knet)=ktx∗uln⁡(u)ln⁡(4)∗(kr+knet)=ktxkr+knetln⁡(4)∗uln⁡(u)=ktxln⁡(4)kr+knet∗uln⁡ut=\frac{k_{\text{tx}}*u}{\log_4(u)*(k_r+k_{net})}=\frac{k_{\text{tx}}*u}{\frac{\ln(u)}{\ln(4)}*(k_r+k_{net})}=\frac{k_{tx}}{\frac{k_r+k_{net}}{\ln(4)}}*\frac{u}{\ln(u)}=\frac{k_{tx}\ln(4)}{k_r+k_{net}}*\frac{u}{\ln{u}}

Multiplying by kr+knetktxln⁡(4)\frac{k_r+k_{net}}{k_{tx}\ln(4)} on both sides we get:

kr+knetktxln⁡(4)t=uln⁡u\frac{k_r+k_{net}}{k_{tx}\ln(4)}t=\frac{u}{\ln{u}}

We want to solve for uu, so remember our goal is to find some function f(t)f(t) such that u=f(t)u=f(t) where tt is our desired TPS, so our target equation should start with u=some function of tu=\text{some function of t}. To get uu isolated we need to find a function g(x)g(x) such that g(uln⁡(u))=ug(\frac{u}{\ln(u)})=u, that way we can say that:

g(kr+knetktxln⁡(4)t)=g(uln⁡u)g\left(\frac{k_r+k_{net}}{k_{tx}\ln(4)}t\right)=g\left(\frac{u}{\ln{u}}\right)

And since g(x)g(x) is defined such that g(uln⁡(u))=ug(\frac{u}{\ln(u)})=u:

u=g(kr+knetktxln⁡(4)t)u=g\left(\frac{k_r+k_{net}}{k_{tx}\ln(4)}t\right)

Or in other words:

Users(TPS)=g(kr+knetktxln⁡(4)⋅TPS)\text{Users}(TPS)=g\left(\frac{k_r+k_{net}}{k_{tx}\ln(4)}\cdot TPS\right)

Now we just have to find a function g(x)g(x) such that g(uln⁡(u))=ug(\frac{u}{\ln(u)})=u.

To help us find such a function let's let y(x)=xln⁡xy(x)=\frac{x}{\ln{x}}, therefore it follows that y−1(x)=g(x)y^{-1}(x)=g(x), so now we have simplified our original problem to finding the inverse of y(x)y(x).

y=xln⁡xy=\frac{x}{\ln{x}}

Let's first define zz to equal z=1y=ln⁡xxz=\frac{1}{y}=\frac{\ln{x}}{x}:

z=ln⁡xxz=\frac{\ln{x}}{x}

We can then multiply both sides by xx to get:

zx=ln⁡xzx=\ln{x}

Raising ee to the power of both sides we get:

ezx=eln⁡xe^{zx}=e^{\ln x}

Simplifying, we get:

ezx=xe^{zx}=x

Let's now multiply both sides by −z⋅e−zx-z\cdot e^{-zx}:

ezx⋅(−z⋅e−zx)=x⋅(−z⋅e−zx)e^{zx}\cdot(-z\cdot e^{-zx})=x\cdot (-z\cdot e^{-zx})

Simplifying, we get:

−z=−zx⋅e−zx-z=-zx\cdot e^{-zx}

Now let's set p=−zxp=-zx, and replace −zx-zx with pp in our equation:

−z=p⋅ep-z=p\cdot e^p

It turns out that there is a function called the Lambert W function (referred to as W(x)W(x)) which has the property that:

W(x⋅ex)=xW(x\cdot e^x)=x

Let's apply Lambert's W function to both sides of our equation:

W(−z)=W(p⋅ep)W(-z)=W(p\cdot e^p)

Using the properties we know about Lambert's W function we can further simplify to:

W(−z)=pW(-z)=p

Since p=−xzp=-xz, we can rewrite this as:

W(−z)=−xzW(-z)=-xz

Since z=1yz=\frac{1}{y}, we can further rewrite our equation as:

W(−1y)=−xyW\left(\frac{-1}{y}\right)=-\frac{x}{y}

If we multiply both sides by −y-y, we now have an expression for xx 🎉:

x=−y⋅W(−1y)x=-y\cdot W\left(\frac{-1}{y}\right)

Hence, we now have a function which meets the desired requirements of g(x)g(x):

g(x)=−x⋅W(−1x)g(x)=-x\cdot W\left(\frac{-1}{x}\right)

And since we already showed that:

Users(TPS)=g(kr+knetktxln⁡(4)⋅TPS)\text{Users}(\text{TPS})=g\left(\frac{k_r+k_{net}}{k_{tx}\ln(4)}\cdot \text{TPS}\right)

We now can now write a formula for the number of users that need to submit proofs in a block to attain a certain TPS on Psy:

Users(TPS)=−TPS⋅(kr+knetktxln⁡(4))⋅W(−1TPS⋅(kr+knetktxln⁡(4)))\text{Users}(\text{TPS})=-\text{TPS}\cdot\left(\frac{k_r+k_{net}}{k_{tx}\ln(4)}\right)\cdot W\left(\frac{-1}{\text{TPS}\cdot\left(\frac{k_r+k_{net}}{k_{tx}\ln(4)}\right)}\right)

To keep our math simple moving forward, let's set the constant cc to equal kr+knetktxln⁡(4)\frac{k_r+k_{net}}{k_{tx}\ln(4)}:

c=kr+knetktxln⁡(4)c=\frac{k_r+k_{net}}{k_{tx}\ln(4)}

Therefore, Users(TPS)\text{Users}(\text{TPS}) can be rewritten as:

Users(TPS)=−TPS⋅c⋅W(−1TPS⋅c)\text{Users}(\text{TPS})=-\text{TPS}\cdot c \cdot W\left(\frac{-1}{\text{TPS}\cdot c}\right)

Let's use some experimental values from Psy's internal testnet to calculate the number of users we need to attain 100,000 TPS on Psy.

  • The proving time required to recursively verify 4 proofs and 4 corresponding delta merkle proofs that link to the nearest common ancestor merkle cap is ~500ms, so kr=0.5k_r=0.5

  • The proof size is ~30kb, so lets say it takes 100ms to send over the network to any where around the world (it fits in a single TCP packet, so think of this as "ping" time)

  • Let's say each user submits an average of 3 transactions per block, so ktx=3k_{tx}=3

To keep our math simple, let's first solve for c=kr+knetktxln⁡(4)c=\frac{k_r+k_{net}}{k_{tx}\ln(4)}

c=kr+knetktxln⁡(4)=0.5+0.13ln⁡(4)=0.63ln⁡(4)≈0.1442695c=\frac{k_r+k_{net}}{k_{tx}\ln(4)}=\frac{0.5+0.1}{3\ln(4)}=\frac{0.6}{3\ln(4)}\approx0.1442695

So Users(100000)\text{Users}(100000) can be written as:

Users(100000)=−100000⋅0.63ln⁡(4)⋅W(−1100000⋅0.63ln⁡(4))\text{Users}(100000)=-100000\cdot\frac{0.6}{3\ln(4)}\cdot W\left(\frac{-1}{100000\cdot\frac{0.6}{3\ln(4)}}\right)

Approximating for 0.63ln⁡(4)\frac{0.6}{3\ln(4)}, we get:

Users(100000)=−14426.95⋅W(−0.000069314718)\text{Users}(100000)=-14426.95\cdot W(-0.000069314718)

To evaluate the Lambert W function, we can use Wolfram Alpha:

wolfram-result.png
(we round up because there is no such thing as 0.166 of a user)

Hence, we arrive at the result that a block must have 174,096 users participating in a block to hit 100,000 TPS!

Users(100000)=174096\text{Users}(100000)=174096

Let's check with our original equation just to make sure:

TPS(u)=# of TransactionsBlock Time=ktx∗ulog⁡4(u)∗(kr+knet)TPS(u)=\frac{\text{\# of Transactions}}{\text{Block Time}}=\frac{k_{\text{tx}}*u}{\log_4(u)*(k_r+k_{net})}

Plugging in u=174096u=174096, we get the correct answer 🎉

TPS(174096)=3∗174096log⁡4(174096)∗(0.5+0.1)≈100000.4392383768 TPSTPS(174096)=\frac{3*174096}{\log_4(174096)*(0.5+0.1)}\approx 100000.4392383768 \text{ TPS}
Carter Jack Feldman

Carter Jack Feldman

Founder of Psy

Copyright © 2026 Psy Protocol. All rights reserved.