NFT Metadata Storage
IPFS's own documentation is direct that a gateway URL is not the canonical address for NFT data, and EIP-4906 defines the events that tell a marketplace when metadata actually changed rather than merely moved. This guide works through where token metadata and media actually live, tokenURI under EIP-721 and uri with {id} substitution under EIP-1155, a five-option storage decision matrix (fully on-chain, IPFS with redundant pinning, Arweave, an HTTPS server, hybrid) and the failure modes a rushed build can run into: pin loss, gateway shutdown, mutable HTTPS metadata and a reveal whose rarity map can leak before it goes public.
Technically reviewed by Olena Zaichenko, D.Sc.
- A gateway URL in tokenURI is a dependency, not an address IPFS's own documentation states that the canonical reference is the ipfs:// URI, and a gateway link only works as long as its operator stays online, which is a different and weaker guarantee than content addressing provides.
- Pinning is opt-in, garbage collection is the default IPFS nodes clear unpinned data under storage pressure by design, so metadata with no active pin has no persistence guarantee at all, regardless of how permanent the collection assumed it was.
- EIP-1155's {id} substitution lets one URI serve an unbounded collection A single uri template resolves to a distinct, fully specified path per token through a mandatory hexadecimal substitution rule, so getting the padding or casing wrong breaks resolution for every affected token at once.
- EIP-4906 tells consumers when content changed, not when only the address did The specification explicitly recommends against emitting an update event when tokenURI changes but the underlying JSON metadata does not, a distinction that is easy to miss on first read.
- Fully on-chain and hybrid storage are engineering patterns, not standards Neither EIP-721 nor EIP-1155 names, prices or compares an on-chain or hybrid storage approach, so both rows of the decision matrix are this guide's own synthesis rather than a sourced claim.
NFT metadata storage is usually treated as a formatting question: put a JSON file somewhere, point tokenURI at it, done. The question that actually decides whether a collection still renders correctly in five years is narrower and gets skipped: once that JSON file exists, who can change it and does the token contract even know when it has? An NFT's on-chain record is deliberately thin: an owner, a token ID and often nothing more than a pointer to something else that describes it. ethereum.org's own explainer states the second half of that model in the plainest terms available: "Additionally, there's usually some information (metadata) attached to it, describing what the NFT represents." That attached information, the name, the image and the trait list, is what this guide means by NFT metadata. The rest of this guide is about where it actually lives, who can change it and what happens when the thing it points to disappears.
In short: the decision matrix below holds the five places NFT metadata actually ends up, each with a typical failure mode drawn from engineering practice rather than a marketing claim. One mistake in a rushed build is writing a gateway URL straight into tokenURI as if it were the permanent address, when IPFS's own documentation says plainly that it is not.
The Decision Matrix: Five Ways to Store NFT Metadata
Where metadata lives is a decision best made explicitly at NFT development time, row by row, rather than inherited from whatever a starter template happened to pick. Every column in the table except Permanence is engineering synthesis rather than a claim sourced to a specification. Only the IPFS and Arweave permanence facts in the Permanence column are sourced directly to their own documentation, quoted below the table.
| Option | Permanence | Who can change it | Cost profile | Failure mode seen in practice | Suits |
|---|---|---|---|---|---|
| Fully on-chain (JSON encoded directly in the contract) | As durable as the contract itself, with no external dependency, provided the image referenced inside the JSON is also stored on-chain rather than pointed at an external file | Only whoever controls a write function the contract author chose to expose, if any exists, or whoever controls the proxy if the contract is deployed behind an upgradeable proxy | The most expensive option to write and update, cost rising with metadata size | A field is fixed at mint with no update path, and the contract carries no room for a value that later needs to change | Small, fixed-attribute collections willing to pay more up front to remove every external dependency |
| IPFS content addressing with redundant pinning | Holds as long as at least one pin survives. Unpinned data is eligible for garbage collection | Nobody in place. A changed file produces a new CID, so an update is a new address rather than an edit. Whoever controls a URI setter or proxy-upgrade path can still repoint the token to a different CID. | An ongoing operational cost, spread across at least one paid or self-hosted pin | The only pin sat on one free-tier node, the node's retention lapses and the CID resolves nowhere | Static art or PFP collections where the metadata is set once and pinning can be operationalized |
| Arweave permanent storage | Positioned by Arweave itself as permanent, decentralized storage | Nobody can edit stored data. A correction is a new upload, and the resulting Arweave transaction ID changes on any new upload; the ID is derived from the signed transaction, not the content alone, an engineering observation about Arweave's transaction model rather than the content-derived addressing IPFS CIDs provide. Whoever controls a URI setter or proxy-upgrade path can still repoint the token away from it. | The cost model is not covered by the sources cited here | A mistake at mint has no in-place fix on the Arweave side. Recovery depends entirely on whether the contract exposes a setter to repoint the token elsewhere | Collections wanting storage that needs no ongoing pin management, accepting an unverified cost model in exchange |
| HTTPS server | Only as durable as the operator's own uptime and business continuity | Whoever controls the server, at any time, without the change being visible in the response itself | Cheapest option day to day, with an ongoing hosting cost, compared with the durable layer's cost profile in its own row | The server starts returning different content after mint, and nothing about the URL discloses the swap | Dynamic, game or asset-backed tokens whose metadata is meant to change on a schedule the team controls |
| Hybrid (durable layer for media, mutable pointer for the JSON) | Only as strong as its least durable layer, usually the mutable pointer | Whatever layer was deliberately left mutable, typically the top-level tokenURI or uri value | Cost follows whichever durable layer is chosen (see its row), plus the mutable layer's own ongoing cost | The team assumes the whole stack inherited the durable layer's guarantee when only one piece of it actually did | Projects that need a durable media layer but still want a cheap, updatable JSON pointer |
The IPFS and Arweave permanence facts in the table are sourced directly to their own documentation. Arweave describes itself plainly: "The Arweave network is like Bitcoin, but for data: A permanent and decentralized web inside an open ledger." It states its own reach on the same short page: "Permanent storage has many applications: from the preservation of humanity's most important data, to the hosting of truly decentralized and provably neutral web apps." Nothing on that page states the mechanism behind the permanence claim, so this guide reports the claim the way Arweave states it. Every other editorial column in the table, including the fully on-chain and hybrid rows in full, is Pharos Production's own engineering synthesis rather than a sourced claim, offered as a practical starting point rather than specification-backed fact.
What NFT Metadata Actually Is, and Who Controls It
Ownership and the token ID live on-chain. The descriptive metadata, especially any image or media file, is typically stored elsewhere and merely pointed to from the chain. Two functions carry that pointer. EIP-721 states plainly why its metadata extension exists at all: "A mechanism is provided to associate NFTs with URIs." Its tokenURI function carries a one-line comment that is the shortest correct definition of what it returns: "A distinct Uniform Resource Identifier (URI) for a given asset." Read literally, tokenURI() does not return a picture, a name or a description. It returns an address, and everything a collector actually sees is fetched or decoded from wherever that address points, depending on whether the URI names a location to retrieve or already carries the data itself.
EIP-1155 covers the same ground, and its uri function is still called once per token ID, just like EIP-721's tokenURI, but it allows a single URI template to serve the entire collection through ID substitution because the client substitutes the ID, so the contract may return the identical template string for every ID, whereas an EIP-721 tokenURI must return the already-resolved URI, usually a base URI joined to the ID on-chain. The mechanism that makes one template usable across every token ID is stated directly: "The URI value allows for ID substitution by clients." That substitution rule is a hard requirement, not a convention: "If the string {id} exists in any URI, clients MUST replace this with the actual token ID in hexadecimal form." The hex form is fully specified down to the padding: "The string format of the substituted hexadecimal ID MUST be leading zero padded to 64 hex characters length if necessary." A URI of https://token-cdn-domain/{id}.json resolves for token 314592 to a lowercase, 64-character, zero-padded hex path with no 0x prefix, and a client that assumes decimal IDs or skips the padding will build the wrong request against every token in the collection. EIP-1155 also defines an equivalent {locale} substitution token for metadata localization, following the same mechanism as {id}.
TokenURI, URI and the Metadata JSON Schema
Building on EIP-721's, EIP-1155 defines its own metadata schema, sharing the same three top-level string fields, name, description and image, and adding fields of its own covered below. The schema's image field is stricter than a generation script may assume. EIP-721's own schema definition states: "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive." That sentence ties the field to a MIME type rather than a file extension, and it recommends a display size and aspect ratio range that is easy to overlook before minting.
EIP-1155 extends those same three base fields with an OPTIONAL decimals field, an OPTIONAL properties object for arbitrary structured attributes and a localization sub-object carrying its own uri, default and locales values for the {locale} substitution mechanism described above. Neither specification restricts the URI scheme a compliant contract may return. EIP-1155's own worked example uses an https:// URL, so a plain HTTPS link is fully conformant and the risk that comes with that choice belongs entirely to whoever operates the server. One IPFS implementation of this pattern is a single base directory: one upload produces a directory CID covering a folder of per-token JSON files, and tokenURI or uri returns that directory's address plus the token's own ID or the literal {id} placeholder, which clients replace with the 64-character hex ID, so one write covers the whole collection's metadata rather than one separate address per token.
Content Addressing: Why a CID Is Not a Gateway URL
A CID is not a place. It is a label derived from the content itself. IPFS's own documentation puts it directly: a CID "is a label used to point to material in IPFS." What makes that label different from an ordinary file path follows in the next sentence: "It doesn't indicate where the content is stored, but it forms a kind of address based on the content itself." Change one byte of the underlying file and the label changes with it: "Any difference in the content will produce a different CID." That property, not an operator's promise, is what makes an IPFS reference verifiable rather than merely convenient.
IPFS itself also defines a mutable naming layer that sits alongside content addressing rather than replacing it: IPNS and DNSLink both resolve a stable name to whichever CID its controller currently publishes, and that target can change over time. A tokenURI built from a raw CID or the canonical ipfs://<CID> form is not affected by this, but a contract or metadata file that instead points through an IPNS name or a DNSLink domain has reintroduced a party who can change the target, which weakens the no-one-can-change-it property IPFS content addressing otherwise provides.
IPFS's own NFT best-practices page names the canonical URL form directly: "IPFS URIs are the canonical representation for an IPFS link, since the ipfs scheme makes it clear and unambiguous that the CID refers to content on IPFS and not some other system." Writing a tokenURI or uri value in that ipfs:// form, rather than as a gateway link, is what keeps the guarantee above intact. The gateway-link tradeoff and its failure mode are covered in the failure-modes section below.
Mutability: Frozen Metadata, Reveals and the EIP-4906 Update Events

EIP-721 never required metadata to be frozen at mint. Its own Rationale section states the choice directly: "The URI MAY be mutable (i.e. it changes from time to time)." It gives a worked example of why that is sometimes the correct design rather than a shortcut: "We considered an NFT representing ownership of a house, in this case metadata about the house (image, occupants, etc.) can naturally change." Freezing the content behind a CID and freezing a token's metadata are not the same guarantee: the bytes an IPFS address resolves to cannot change without producing a new CID (the mutable name layers IPNS and DNSLink are an exception to content-derived addressing), and an Arweave transaction ID likewise changes on any new upload; the ID is derived from the signed transaction, not the content alone, an engineering observation about Arweave's transaction model rather than IPFS-style content addressing. Even so, the token's metadata is only actually frozen if the tokenURI or uri value pointing at that address has no setter function, or that function exists but a one-way freeze flag has permanently locked it, and sits behind no upgradeable proxy that could swap it for a different address later. A tokenURI built from live contract state, such as an on-chain generator reading a variable that can still change, is not frozen either, whatever storage layer its output happens to point to. The specification does not pick a policy. It leaves the policy to the contract author and expects the consumer to find out which one applies.
Confirming which policy actually applies to a deployed contract, rather than assuming one, is itself a short checklist: any function that can change the stored URI, who holds the role allowed to call it, whether a one-way freeze flag has permanently locked any such function, whether the contract is deployed behind an upgradeable proxy and who controls its admin, whether the returned URI is content-addressed, whether the image and media URIs inside the JSON metadata are themselves content-addressed and whether the update-event history shows a prior change. This checklist is engineering synthesis, not a specification requirement.
EIP-1155 gives consumers a way to find out without polling, and it goes further than an optional courtesy: "Changes to the URI MUST emit the URI event if the change can be expressed with an event (i.e. it isn't dynamic/programmatic)." Only the initial emission at mint is left to the implementer's discretion: "An implementation MAY emit the URI event during a mint operation but it is NOT mandatory." Once an event has been emitted for a given ID, the contract is bound to the latest event: "The uri function MUST return the same value as the latest event for an _id if it was emitted." EIP-4906, itself an OPTIONAL extension that an EIP-721 contract must explicitly implement rather than something the base standard requires, answers a related but different question for EIP-721 contracts: EIP-1155's URI event confirms that the uri string itself changed, while EIP-4906's events confirm that the underlying JSON metadata changed, with an unambiguous emission rule of its own: "The MetadataUpdate or BatchMetadataUpdate event MUST be emitted when the JSON metadata of a token, or a consecutive range of tokens, is changed." It also draws a distinction that is easy to miss on first read, between the address changing and the content changing: "Not emitting MetadataUpdate event is RECOMMENDED when the tokenURI changes but the JSON metadata does not." A contract that migrates from one IPFS gateway to another, for example, is expected to stay quiet about it, because the JSON the gateway serves has not actually changed.
A marketplace or indexer that has already crawled a token typically caches its metadata rather than re-fetching it on every view. Where EIP-4906 or EIP-1155's URI event is wired up, that cache can refresh in an event-driven way: a listener watches for the update event and re-fetches only the tokens it names. Where no such listener exists, the alternative is periodic or on-demand manual re-fetching, so a metadata change can sit unreflected until something external triggers a re-crawl. This is a general description of platform behavior, not a claim about any specific marketplace or indexer.
None of the specifications above use the term reveal. It is this guide's own name for a specific application of the mutability rule they do define: a collection mints with every token pointing at one placeholder tokenURI, a shared placeholder that sits uneasily with EIP-721's own notion of a distinct URI for a given asset, then, for an EIP-721 contract with EIP-4906 support, a single transaction swaps the base URI and emits BatchMetadataUpdate(_fromTokenId, _toTokenId), using the event's actual parameter names, covering the whole range in one event; an EIP-1155 contract has no batch equivalent and re-emits its URI event once per token ID instead. Either way, the swap tells indexers and marketplaces to refresh every affected token. The mechanism is nothing more than the mutability EIP-721 already allows plus the update event EIP-1155 or EIP-4906 already defines. In a design where the token-to-metadata mapping is fixed before the reveal, the reveal transaction itself assigns nothing new: the trait mapping it exposes was already fixed earlier. Its pending calldata still exposes the new base URI before the transaction is mined, though, leaking the rarity map a block early and letting a fast reader snipe underpriced listings before indexers refresh. Offset-at-reveal designs, which instead draw a random starting-index offset inside the reveal transaction itself, move the randomness risk into that same transaction, where it can be read and raced directly in the mempool. One real risk sits earlier: watching the mempool or the storage layer for the real metadata before the reveal is public lets a party see the rarity map ahead of everyone else, enough to snipe underpriced resale listings or, if minting is still open, mint selectively toward the tokens that turned out valuable. A second leak path is the real metadata being uploaded to a predictable URL or CID before the reveal fires, discoverable by anyone who guesses or crawls the storage path early. That risk is an engineering observation about how a reveal is typically implemented, not a claim from any specification cited in this guide.
A second, distinct risk sits at mint rather than at reveal, when trait assignment is itself derived on-chain from a source like a block hash or prevrandao. Both are predictable enough that a minter can simulate the outcome before a transaction is even mined and revert or skip any mint that would land a bad roll, moving the race to the mint transaction itself. Mitigating that is again outside anything the specifications define. Assigning traits from a source the minter cannot preview, such as an oracle-supplied random value requested only after the mint window closes, removes the incentive to simulate. A commit-reveal pattern, where the trait assignment is committed as a hash before the real metadata is published, is a second option: a genuine cryptographic hash commitment rather than a purely structural safeguard. It proves the mapping was not changed after the fact, though the team that made the commitment still knows what it committed to, so commit-reveal can be paired with randomness drawn only after the mint window closes rather than relied on alone. It adds contract complexity weighed against the collection's actual exposure to sniping. Neither approach is mandated in the metadata standards themselves. Both live entirely in how the minting contract is designed around them.
Failure Modes in Practice: Pin Loss, Gateway Shutdown and Mismatched Media Types
IPFS does not keep data forever by default. Pinning is what prevents it from disappearing. IPFS's persistence documentation states the default behavior plainly: "Storage is finite, so nodes need to clear out some of their previously cached resources to make room for new resources." Pinning is the explicit opt-out from that default: "To ensure that data persists on IPFS, and is not deleted during garbage collection, data can be pinned to one or more IPFS nodes." A pinning service is simply a business built around holding that opt-out for a fee: "These services run lots of IPFS nodes and allow users to pin data on those nodes for a fee." This failure mode follows directly from that default. A team pins metadata to one node at mint, that node's retention policy or the team's own account lapses, and the CID that used to resolve now resolves nowhere, even though the token itself is still perfectly valid on-chain. Redundant pinning is the structural fix rather than a workaround: pinning the same CID through more than one provider, and keeping at least one pin under the project's own operational control rather than a single third party's, means a single lapsed account or a single pinning service closing down does not, by itself, take the metadata offline.
Gateway dependence is a different-shaped failure from pin loss, but converges on the same broken result. IPFS's NFT best-practices page draws the canonical-versus-convenience line directly: "HTTP gateways provide interoperability for legacy user-agents that cannot resolve IPFS URIs natively." That purpose does not make a gateway link canonical, and the same page says so directly: "Gateway links are great for interoperability, but they should not be the primary or canonical link to your data on IPFS." Its failure mode follows in the next sentence: "While an IPFS URI will remain accessible as long as anyone on IPFS has the data, a gateway link can fail if the gateway operator goes offline." What is actually lost when a tokenURI is written as a gateway URL is narrower than it first looks: a path-style gateway URL still contains the CID itself, so the content stays verifiable and a client can rewrite the link to a different gateway on its own. What is lost is availability independence: the token now depends on that one operator staying online instead of on the content-addressed guarantee an ipfs:// URI carries directly.
Two further failure modes have no specification behind them and are written here as engineering observations rather than sourced claims. Mutable HTTPS metadata carries no content-addressing property at all, so nothing prevents the server operator from changing what a URL returns after mint, silently and without any version marker, which is the opposite problem from IPFS in that here nothing forces a change to become visible. And a metadata JSON's own image field only constrains the value to a URI of mime type image/*. Nothing in that constraint stops a metadata-generation script from writing a URI that serves the wrong content type once fetched, a mismatch that typically surfaces only as a broken render rather than as any error returned to the contract or the minting flow itself.
How Pharos Production Helps
An NFT's metadata strategy is a decision made once, at contract design time, that determines whether the collection is still renderable in five years. Our NFT development team builds token contracts around the mutability policy that fits the project, whether that means metadata frozen by removing any setter or proxy-upgrade path, or by locking the setter with a one-way freeze flag, over an IPFS or Arweave reference, a scheduled reveal wired through EIP-1155's URI event, re-emitted once per token ID with no batch equivalent, or through EIP-4906's BatchMetadataUpdate event covering a whole range at once or a hybrid stack where only the pieces that actually need to move are left mutable.
Metadata storage is one layer of a wider blockchain services practice that also covers the smart contract development the tokenURI and uri functions live inside, from the EIP-721 or EIP-1155 interface itself through to the pinning and update strategy wrapped around it. Our crypto and Web3 development work for token-based products draws on the same standards this guide cites, and our Web3 stack guide covers where a storage layer like this fits inside the rest of a blockchain product's architecture.
Sources: Ethereum Improvement Proposals on eips.ethereum.org (EIP-721, EIP-1155 and EIP-4906); the IPFS documentation on docs.ipfs.tech (content addressing, persistence and the NFT best-practices guide); arweave.org; ethereum.org. Read 23 September 2026. Engineering guidance, not financial or legal advice.
FAQ
Quick answers to common questions about custom software development, pricing, process and technology.
Type to filter questions and answers. Use Topic to narrow the list.
Showing all 6
No matches
Try a different keyword, change the topic or clear filters
-
Usually not. The token's ID and its ownership record live on-chain.
The descriptive metadata, the name, the description, the image and any attributes, typically lives off-chain, referenced through the tokenURI or uri function rather than stored inside the contract itself. Only the fully on-chain storage option actually keeps the metadata JSON on-chain, and its cost is the tradeoff a team is accepting by choosing it over the other four options.
-
tokenURI and uri are both called per token ID; an EIP-721 contract can in principle return a completely different URI for each call, with no shared pattern required. EIP-1155's uri function is still called once per token ID in the same way, but it supports a single URI template through {id} substitution, so one pattern can generate a distinct, fully specified path for every token ID with the client, not the contract, doing the substitution.
The practical consequence is that an EIP-1155 client has to implement the hexadecimal substitution rule correctly, or every token built from that template resolves to the wrong URI at once, rather than one token failing in isolation.
-
The token itself stays perfectly valid on-chain, and nothing about the mint or the ownership record changes. What breaks is purely a rendering problem: a marketplace or wallet resolving that gateway URL gets a failed request instead of an image, unless the client rewrites the embedded CID to another gateway, because the URL depended on one gateway operator staying online rather than on the content-addressed guarantee an ipfs:// URI actually carries.
Writing the canonical ipfs:// form into tokenURI removes the dependence on any single gateway operator, since any wallet or marketplace client can resolve it through whichever gateway or local node it prefers; it does not remove the separate pin-loss failure mode, and any HTTP fallback for a client that cannot resolve ipfs:// natively is the client's own concern, not something the tokenURI value itself provides.
-
It depends on the contract and on the storage layer, not on anything the token standards themselves mandate. EIP-721's own specification states that the URI may be mutable, and gives an explicit example of metadata that is meant to change over time.
The content behind a given IPFS reference cannot change without producing a new CID, and an Arweave reference's transaction ID likewise changes on any new upload, an engineering observation about Arweave's transaction model rather than IPFS-style content addressing, but that only freezes a token's metadata if the tokenURI or uri value pointing at that address has no setter function, or has one permanently locked by a one-way freeze flag, and sits behind no upgradeable proxy; a tokenURI built from contract state changes whenever that state changes, whether or not the underlying content address does. Where a tokenURI points at a server the team controls, the metadata behind that tokenURI can change at will, not the tokenURI string itself, with or without an update event to announce it.
-
Through an explicit event, when the contract emits one. EIP-1155 requires the URI event to fire whenever a change to the uri value can be expressed as an event, though emitting it at mint itself is left optional.
EIP-4906, an OPTIONAL extension an EIP-721 contract must explicitly implement, answers the equivalent question but at the JSON-metadata level rather than the URI-string level: its MetadataUpdate and BatchMetadataUpdate events fire when the underlying JSON changes, and emitting one is explicitly not recommended for a tokenURI-only change. A contract that changes its metadata without emitting the applicable event gives an indexer no signal at all, and the update is only discovered the next time something happens to re-fetch or re-decode that specific token.
-
None of the token standards use the word reveal. It describes an application of ordinary mutability: a collection mints with every token pointing at one placeholder tokenURI, then a single transaction emits an update event, batched for an EIP-721 contract with EIP-4906 support or re-emitted per token ID under EIP-1155, telling marketplaces and indexers to refresh every affected token.
In a fixed-mapping design the transaction itself assigns nothing new, though its pending calldata still exposes the new base URI before it is mined, leaking the rarity map a block early; an offset-at-reveal design instead draws its randomness inside that same transaction, moving the risk into something that can be read and raced directly. A further risk is earlier leakage: real metadata uploaded to a predictable URL or CID before the reveal, or trait assignment taken on-chain at mint from a predictable source like a block hash, which a minter can simulate and revert to avoid a bad roll.
I work with startup founders who need a dedicated software development team but don’t want to gamble on hiring, random outsourcing, or opaque delivery.
Most founders face the same problem sooner or later.
Early technical and team decisions lock the product into tech debt, slow delivery, missed milestones and constant re-hiring. By the time this becomes visible, fixing it is already expensive.As a CTO and software architect, I help founders design, build and run dedicated development teams that work as a true extension of the startup. Not as a black-box vendor.
My focus is on complex products where mistakes are costly:
- Web3 and blockchain platforms
- FinTech and regulated products
- High-load startup systems
- MVP → scale transitions
We don’t do body-shopping.
We don’t sell generic outsourcing.Instead, we help founders:
- build the right team structure from day one
- keep technical ownership and transparency
- scale delivery without losing control
- avoid vendor lock-in and hidden risks
Teams are aligned with the product roadmap, business goals and long-term architecture. Not just short-term velocity.