Why NFT notifications in the app arrive late
A delayed push notification about NFT bids is almost never born in the push service itself.
It accumulates along the chain: the app or backend polls the blockchain, waits for transaction confirmation, matches the event against the user's subscriptions — and only then sends the notification.
Each segment adds its own seconds, and in bidding where a bid is outbid within minutes, that is enough for the user to learn about the event when it is already irrelevant.
The first source of delay is blockchain polling. If the app queries the network on a schedule, a fixed interval passes between two checks, and an event that falls within it waits for the next cycle.
The less frequent the polling, the higher the chance of missing the moment when the bidding can still be won. In some solutions, the check only runs when the app is open — in the background, NFT notifications do not arrive at all.
The second source is the moment the event is recorded. A transaction first enters the mempool and only then gets confirmed. If the notification is built on an unconfirmed event, it may arrive and then roll back along with a chain reorganization.
If you wait for finality, the push delay grows, and missing the bidding becomes more likely. A compromise is needed here: an early notification about a bid appearing and a separate one about confirmation.
The third segment is notification delivery to the device. Mobile platforms restrict background work: the system may suspend the app, postpone a network request, or group several notifications into one.
A separate problem is matching an event against subscriptions: if a user follows a dozen collections, and the filter is built on the device side, some events are filtered out even before sending.
We break this chain down link by link and find exactly where time is lost: in the polling schedule, in the confirmation logic, or in the delivery rules. Next — how this gets closed.
What a well-tuned bidding notification channel delivers
The speed at which NFT bidding notifications are delivered is determined not by the speed of sending, but by how the app receives them in the background.
If you rely only on periodic server polling, the "bid outbid" event reaches the owner with a delay of minutes — by which time the auction has already closed.
A persistent connection to the server plus a system delivery channel reduce this gap to seconds, and a decision on the bid is made while the lot is still active.
The share of successful impressions depends on two things: the notification priority and the state of the app itself. If there is a single channel for all events, an important bid gets lost among service messages and promotional reminders.
Splitting into separate categories with different priorities and sounds raises the impression share, while grouping duplicate events by lot removes visual noise — the user sees one notification instead of five.
Missed events almost always come down to one thing: the app has been unloaded from memory or notifications are disabled at the system level.
Here a combination works — saving the event on the server and re-delivering it on the next launch, plus a soft permission request at the moment the user places a bid for the first time, rather than on the first screen. This reduces the number of lost auctions without pressuring the user.
The load on the app does not grow in the process: background tasks are handled by the system mechanism rather than a constant loop inside the process.
The app does not hold extra connections and does not drain battery in the background — notifications arrive even when it is closed, and on opening only the current state of the lot is pulled in.
Approaches to tracking trading events and their limitations
Trading events can be received in three ways: periodic polling, streaming subscription, and a hybrid scheme. The difference is not about "correctness" but about what requirements you set for latency, cost, and resilience. Below is how this works in practice and where each option breaks down.
| Option | When it fits | Limitations |
|---|---|---|
| Periodic polling | Infrequent trading, insensitivity to latency of tens of seconds | Latency grows with the interval; with frequent requests, load increases and so does the risk of being cut off by rate limits |
| Streaming subscription | Active trading, reaction within seconds is needed | Requires reconnection and catching up on the missed window when the connection drops |
| Hybrid scheme | Mixed activity: subscription for hot lots, polling for the rest | Harder to maintain: two sources need to be reconciled without duplicates |
How the scheme is chosen
The key parameter is how many trading events arrive per unit of time and how critical latency is. If a lot is outbid once a minute, polling every 10–15 seconds provides acceptable freshness and does not require a persistent connection.
If bids come in a stream, a subscription wins: the event arrives almost immediately, rather than after the next cycle.
Where the extreme options break down
A pure subscription is vulnerable to disconnects: when the connection is lost, some events are missed, and without a catch-up mechanism the user sees a stale state. Pure polling hits rate limits and does not scale to many active lots.
The hybrid scheme covers both cases but requires deduplication — the same event may arrive from both the subscription and the polling.
We break down how this is handled in the app: choosing a scheme for the trading profile, reconnecting with catch-up on the missed window, and delivering NFT notifications without duplicates.
How we build NFT notification delivery
Bid notifications are not a single call to a push service, but the route of an event from the blockchain to the phone screen. The stakes are high: a missed signal about a bid on a lot means a lost auction.
That is why we design delivery as a separate subsystem with idempotency, retries, and observability, rather than as a "send a push" function.
- Audit of events and scenarios. We break down which events actually generate a notification: a new bid, an outbid bid, lot ending, win, cancellation. For each one we record the priority, the validity period, and what to do if the event is stale by the time of sending.
- Routing scheme. We build the rules: to whom, through which channel, and with what delay an event is sent. We take into account the user's subscriptions, quiet hours, rate limits, and the merging of several bids on a single lot into one message so as not to flood a person with a dozen signals.
- Setting up delivery channels. Push as the primary channel, an event feed inside the app, and email for critical statuses such as a win. For each channel we define the priority, the behavior on failure, and the rules for switching to a backup.
- Setting up push. We register devices, store tokens linked to an account, and handle their rotation and revocation when logging out of the profile. Separately, we configure notification groups and sound so that the bid signal differs from service messages.
- Delivery verification. We run the scenarios on a staging environment: delivery with the app active, in the background, and after a restart, behavior when a channel is unavailable, the correctness of retries, and the absence of duplicates. We look at the share of successful deliveries and the time from event to display.
- Observability. We log the path of each notification — from the appearance of the event to the user opening it. This allows us to investigate "it didn't arrive" complaints based on facts rather than guesswork.
- Handover and guidelines. We hand over the routing scheme, channel configuration, delivery dashboard, and instructions for adding new types of events without rebuilding the logic.
This order removes the main risk — the silent loss of notifications, when a bid went through but the user never learned about it.
What the client receives after implementation
After implementing NFT auction notifications, the client receives not a "working feature" but a set of artifacts that allow the system to be operated, extended, and handed over to another team without us. Below is what specifically remains in the repository and the internal knowledge base.
- Notification service configurations — rules for subscribing to auction events, message templates by type (outbid, lot won, auction ended), grouping settings so the user does not receive an avalanche of pushes during an active lot.
- Flow diagrams — from the event on the platform to delivery to the device: where the notification is generated, where duplicates are filtered out, where the queue is stored, and what happens when the recipient is unavailable.
- Access policies — separation of rights for sending, editing templates, and viewing delivery statistics; separately — rules for storing device tokens and subscribers' personal data.
- Integration documentation — description of events and formats that the application accepts and returns, with examples of requests and responses for the team that will connect new auction types.
- Operational regulations — procedures for delivery failure, for complaints about notification frequency, and for scheduled maintenance on the platform side.
- Delivery dashboard — metrics on sent, delivered, and opened notifications broken down by event type, so degradation can be seen before users notice it.
- Rollback instructions — how to revert to the previous distribution configuration and what checks to run after the rollback.
The set is designed so that the client's team can subsequently add new auction types and change notification texts on its own, without coming to us for every edit.
If you already have some of the artifacts — we will discuss the task and come back with an assessment of what needs to be supplemented and what can be reused.
Case study: how we sped up delivery of auction notifications
The client — a digital asset marketplace built on OpenSea-compatible contracts — complained that bids at auctions were "going stale": a user would learn about a bid being outbid minutes later, when the auction had already closed.
Pre-work metrics: median delivery of a new bid notification — 40 seconds, share of successful displays — 71%, missed events under peak load (a mass collection drop) — up to 9% of the total number of bids.
What was wrong
The application polled the indexer on a schedule: the client hit the API once every 15 seconds and compared a snapshot across tracked lots. During spikes in activity, requests queued up, and some responses were dropped on timeout — hence the missed events.
On top of that, filtering for "my lots" happened on the client, meaning the phone pulled the entire stream of collection events, even when the user wasn't looking at the screen.
What we changed
We moved delivery to a server-side event stream: the indexer publishes bid changes to a bus, a worker matches them against user subscriptions and sends a targeted push.
Lot and bid-threshold filtering was moved to the server, and we added idempotency by event hash — a repeated delivery doesn't duplicate the notification, and an event lost during a connection drop is re-sent from the queue.
For offline users we keep a catch-up window: when they return to the app, they receive a summary of all missed auctions.
Result
Median delivery — 3 seconds instead of 40, the share of successful displays grew from 71% to 98.6%, missed events at peak — 0.2% versus 9%.
We separately measured the "managed to outbid" metric: the share of users who reacted before the lot closed tripled — and that's already about the client's money, not about infrastructure.
The case is instructive because the bottleneck wasn't in the delivery channel but in the architecture: the client was taking on work that the server should be doing.
If your NFT auction notifications arrive with a delay or get lost — describe the task, and we'll come back with an estimate and a plan.
How does streaming subscription differ from periodic polling?
Periodic polling is a cycle in which the application itself asks the server every N seconds whether new lots have appeared.
The delay between the real event and the notification equals half the interval on average and the full interval in the worst case: with polling every 30 seconds, a bid on a rare lot goes to a competitor who saw it 25 seconds earlier.
Reducing the interval means linearly growing the load: each active user turns into a stream of requests, most of which return an empty response.
A streaming subscription flips the model: the client opens a long-lived connection once, and the server itself pushes the event at the moment it appears.
The delay drops to the delivery time of a single message — fractions of a second instead of tens of seconds, and it does not depend on the number of subscriptions.
The load is proportional to the number of real events, not the number of users multiplied by the polling frequency: the server does not waste resources on checks "into the void."
The price is in the complexity of maintenance.
A long-lived connection must be maintained: mobile networks tear it down when switching between towers and when the application is minimized, so reconnection with subscription restoration, delivery confirmation, and deduplication of repeatedly arriving events are needed.
With periodic polling there is none of this — the state is stateless, the request either worked or will repeat in the next cycle.
In practice, a hybrid is chosen: streaming subscription for urgent events — new lots, price changes, trading close, and periodic polling as a safety net for background summaries and recovery after a long offline.
This way the delay of critical notifications remains minimal, while the load and complexity remain manageable.
Common technical concerns
Trade notifications are not an "event-driven push" but a pipeline with guaranteed delivery. Below are the points that customer engineers most often clarify before launch.
How do you guarantee delivery if some devices are offline?
A trade event is first recorded in a queue with write confirmation, and only then distributed across channels. If a device is unavailable, the notification stays in the queue and is delivered on the next connection rather than being lost.
For critical events — a bid has been outbid, a lot has been sold — we duplicate via a backup channel so the user does not miss the moment.
What happens under increased load during peak trading?
The pipeline scales horizontally: event handlers and dispatch are separated, so a bottleneck at one stage does not block the others. During a spike in activity, workers are added, and the queue smooths the peak — delivery latency remains predictable.
How will this integrate into our existing infrastructure?
We connect to your backend via events or webhooks — without rewriting the current trading logic. If you already have an authentication system and user profiles, we use them; device tokens and subscription settings are stored separately so as not to touch the core data.
Can individual notification types be rolled back or disabled?
Yes. Event types and channels are managed by configuration: you can disable a specific type, reduce the frequency, or switch a user to another channel without an app release. This also provides a fallback path if an external delivery service is unavailable.
Let's discuss your notifications task
To come back with an estimate and a work plan rather than generalities, we need a minimum of input about your product.
NFT notifications are not a single feature but a combination: an event source (marketplace, auction, blockchain events), filtering rules for a specific user, and a delivery channel to the device.
The more precisely you describe the current landscape, the faster we will move from discussing the task to a concrete plan.
What we will cover on the first call
- Event sources. Where the bidding data comes from: your own backend, external marketplaces, direct events from the network. This determines whether a separate aggregation layer is needed and how often the sources should be polled.
- Subscription rules. Which collections, lots, and thresholds the user wants to receive NFT notifications for — and where these rules are stored: on the client, on the server, or in both places.
- Delivery channels. Push via system services, in-app messages, fallback channels for cases when push does not get through. We will work out what is critical for your scenario.
- Current architecture. What already exists in the app: authorization, user profile, blockchain integration. This will show what we can reuse and what will have to be built.
- Load and behavior. How many users, how many events at peak, how often lots change. This determines the queueing and deduplication scheme.
- Platforms and constraints. iOS and Android handle background notifications and permissions differently — we take this into account in the plan, not after launch.
- Readiness criteria. What "works" means to you: delivery latency, delivered share, absence of duplicates. We will lock this down before the project starts.
What to send before the call
- A link to the app or a description of the current stack and how the backend is structured.
- A list of sources from which bidding events should come.
- Example scenarios: which specific NFT notifications and under what conditions the user should receive.
- Timeline constraints and what has already been done on this task.
Describe the task in free form — we will come back with an estimate, a stage-by-stage work plan, and a proposal for starting the project. If some of the input is not ready yet, we will work through it together on the call and record the assumptions in the plan.







