npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sol-priority-fee

v0.1.0

Published

Recommended Solana priority fee from what recent transactions paid (zero-dependency CLI)

Downloads

252

Readme

sol-priority-fee

Tests npm

A zero-dependency Node.js CLI that recommends a Solana priority fee from what recent transactions actually paid, or from the fee floor of the accounts your transaction touches.

npx sol-priority-fee

Why not just call getRecentPrioritizationFees?

When this tool was built, that RPC method, called without accounts, returned a fee of 0 for all 150 of the most recent slots on mainnet. Percentiles of zeros tell you nothing, so the default mode reads what non-vote transactions really paid in recent blocks instead. The per-account version of the same RPC method is still useful, and it is available with --account.

Usage

# Recommendation from what transactions paid in the last 3 blocks
sol-priority-fee

# Prices for a 60,000 compute unit limit
sol-priority-fee --units 60000

# Fee floor for landing a transaction that locks these accounts as writable
sol-priority-fee --account <address> [--account <address> ...]

# Keep refreshing every 10 seconds (Ctrl+C to stop)
sol-priority-fee --watch

# Machine-readable output
sol-priority-fee --json
sol-priority-fee --watch --json --interval 5

Requires Node.js 18 or newer (CI runs on 20 and 22). No dependencies.

Options

| Option | What it does | | --- | --- | | --account <address> | Fee floor for landing a transaction that locks this account as writable. Repeatable, up to 128. Addresses are validated as 32-byte base58 before any RPC call. | | --units <n> | Compute unit limit used to convert between lamports and micro-lamports per compute unit. Default 200000, maximum 1400000. | | --watch | Keep refreshing until you press Ctrl+C. A failed refresh is reported and retried; after 5 failures in a row it stops with exit code 1. | | --interval <s> | Seconds to pause between refreshes with --watch. Default 10, from 5 to 3600. The time to fetch the data comes on top of this. | | --json | Print JSON: one pretty object for a single run, one compact line per refresh with --watch. | | --rpc <url> | RPC endpoint. Overrides the environment variable. | | -v, --version | Print the version. | | -h, --help | Show help. |

RPC endpoint

The endpoint comes from --rpc, then the SOL_PRIORITY_FEE_RPC environment variable, then the public mainnet RPC, which rate-limits heavily. Use your own endpoint for anything beyond a quick try.

export SOL_PRIORITY_FEE_RPC="https://your-rpc-provider.example/your-key"
sol-priority-fee

Only the hostname of the endpoint is ever printed, because RPC URLs often contain API keys.

Cost per refresh:

  • Default mode: getSlot plus getBlock for 3 recent blocks, about 4 calls. Blocks are large, so on a free tier use a longer --interval.
  • --account mode: 1 call (getRecentPrioritizationFees).

Output

Default mode reads the priority fee each non-vote transaction paid in the 3 most recent blocks. low, medium and high are the 50th, 75th and 90th percentile.

Priority fee recommendation

  level      lamports/tx  micro-lamports/CU
  low                  8                 40
  medium             607              3,035
  high             5,193             25,965

Per-CU price assumes a 200,000 compute unit limit (change it with --units).
Based on 1,052 non-vote transactions in 3 recent blocks (slots 455731533 to 455731535) via mainnet.helius-rpc.com.
56% of them paid a priority fee.
low, medium and high are the 50th, 75th and 90th percentile of the priority fee those transactions paid.

--account mode shows, per slot, the fee the RPC reports for landing a transaction that locks the account as writable, over the last 150 slots (about 60 seconds). This is a quiet account, so most of it is 0:

Priority fee floor for 1 account

  level      lamports/tx  micro-lamports/CU
  low                  0                  0
  medium               0                  0
  high                 1                  4

Lamports per transaction assume a 200,000 compute unit limit (change it with --units).
Based on 150 recent slots (455736543 to 455736692, about 60 seconds) via mainnet.helius-rpc.com.
For each slot the RPC reports the fee needed to land a transaction that locks this account as writable.
low, medium and high are the 50th, 75th and 90th percentile across those slots.
This is a floor for getting in, not a bid to win: if the account is contested, pay above it.
A low fee of 0 means at least half of the recent slots needed no priority fee for this account.

JSON (default mode):

{
  "mode": "recent-transactions",
  "time": "2026-10-11T17:39:35.566Z",
  "rpc": "mainnet.helius-rpc.com",
  "computeUnits": 200000,
  "slotRange": { "from": 455736632, "to": 455736634 },
  "blockCount": 3,
  "sampleCount": 1498,
  "payingCount": 1237,
  "levels": {
    "low": { "percentile": 50, "lamports": 809, "microLamportsPerUnit": 4045 },
    "medium": { "percentile": 75, "lamports": 4770, "microLamportsPerUnit": 23850 },
    "high": { "percentile": 90, "lamports": 10350, "microLamportsPerUnit": 51750 }
  }
}

With --account the object has "mode": "account-floor", an accounts array and a zeroCount instead of the block fields.

Using the numbers

The value to set on a transaction is the micro-lamports per compute unit price, together with a compute unit limit. Use the same --units as the limit you set, so the lamports figure matches what you will pay.

const { ComputeBudgetProgram } = require('@solana/web3.js');

const instructions = [
  ComputeBudgetProgram.setComputeUnitLimit({ units: 200000 }),
  ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 3035 }),
  // ...your instructions
];

Priority fee in lamports is price in micro-lamports per CU * compute unit limit / 1,000,000.

Programmatic use

const { resolveEndpoint, sampleRecentFees, summarizeFees } = require('sol-priority-fee');

(async () => {
  const endpoint = resolveEndpoint(null);
  const sample = await sampleRecentFees(endpoint, {});
  const summary = summarizeFees(sample, { computeUnits: 200000 });
  console.log(summary.levels.medium.microLamportsPerUnit);
})();

Honest limits

  • A recommendation is a statistical guess from a small, recent sample, not a guarantee of inclusion. Fees can spike faster than any sample shows.
  • Default mode samples 3 blocks. It excludes vote transactions and counts only the priority fee: the total fee minus 5,000 lamports per signature. Tips sent as separate transfers (for example to a bundle service) are not counted.
  • The lamports-per-transaction figure in default mode is what transactions paid, whatever their compute unit limit was. The micro-lamports-per-CU figure converts it using --units, so it is only exact for transactions with that limit.
  • --account mode covers about 60 seconds. Accounts go quiet quickly, so 0 is common for anything that is not contested right now.
  • The per-account figure is a floor for getting in. If many transactions compete for the same account, pay above it.

Exit codes

| Code | Meaning | | --- | --- | | 0 | Success, or stopped with Ctrl+C in watch mode | | 1 | RPC error, no usable data, or watch mode gave up after 5 failed refreshes | | 2 | Invalid options or addresses |

Development

npm test

Tests use Node's built-in test runner and a mock RPC helper, so they run offline. See CONTRIBUTING.md.

License

MIT