devoracles.

Web3 development services: the complete infrastructure guide
Developer Tools & SDKs

Web3 development services: the complete infrastructure guide

A Web3 application can pass every unit test and still fail at the only moment users care about: a live transaction, against live state, under a live RPC rate limit. The contract is deployed. The frontend signs correctly.

Then an indexer lags three blocks, an RPC provider meters an expensive trace call as a heavy request, and the UI displays a stale collateral ratio.

That is the actual surface area of web3 development services. Not “blockchain development” in the abstract. A chain of dependencies with different latency profiles, billing units, failure modes, and operational owners.

The 2026 stack is also less forgiving than it used to be. The Graph Hosted Service is fully deprecated. Teams still treating indexing as a free hosted afterthought now have to choose between The Graph Network and managed alternatives. RPC pricing is increasingly measured in weighted consumption units, not raw request counts. Framework choice determines local iteration speed, but it also shapes CI behavior, plugin maintenance, and onboarding cost.

For project managers evaluating blockchain development services—or teams considering dapp development outsourcing—the useful question is not “which vendor is best?” It is: where does deterministic application behavior depend on infrastructure you do not operate yourself?

The expensive Web3 outage is rarely a chain outage. It is usually a bad assumption about the layer sitting between the chain and the user.

The six-layer Web3 infrastructure stack: find the real dependency

Web3 infrastructure providers operate across six connected layers:

1. Blockchain networks — execution and settlement. Ethereum, L2s, sidechains, testnets. This is the base state machine.

2. Node access — RPC and WebSocket endpoints exposing that state machine to applications.

3. Data services — indexers, subgraphs, event pipelines, archive data, analytics layers, and price feeds.

4. Smart contracts — protocol logic, deployment artifacts, verification, upgrade paths, and execution interfaces.

5. Wallet infrastructure — account connection, signing, transaction simulation, embedded wallets, custody flows.

6. Applications — frontend, backend, alerting, business logic, user sessions, and observability.

Teams often purchase “web3 integration services” as though this were one category. It is six categories with six different incident patterns.

A slow RPC endpoint and a delayed subgraph can produce nearly identical symptoms in a dashboard: stale balances, missing positions, wrong token metadata. The remediation is completely different. One needs request profiling and endpoint failover. The other needs indexer monitoring, schema review, or a fallback query path.

The cleanest architecture separates write-path truth from read-path convenience:

  • Writes go through an explicitly selected RPC provider, with simulation and receipt monitoring.
  • Critical reads that affect transaction construction should come from current chain state where practical.
  • Historical and aggregate reads belong in an indexing layer.
  • UI state must disclose or handle indexing lag instead of quietly treating indexed data as instant finality.
  • Offchain data feeds need their own freshness and deviation policies. A price displayed at the wrong timestamp is not “slightly stale” if it drives liquidation or swaps.

For an oracle-aware application, this separation becomes non-negotiable. You are already managing feed heartbeat windows, deviation thresholds, and update cadence on the data side. Do not add unmeasured RPC lag and subgraph lag on top, then call the resulting number “the market price.”

What belongs in-house and what does not

The first operational mistake is outsourcing the wrong layer. Managed services are good at commodity node access, broad chain coverage, burst capacity, and operational uptime. They are less useful as a substitute for application-specific data correctness.

Keep these close to the protocol team:

  • contract ABI ownership and release artifacts;
  • event schemas and data model assumptions;
  • oracle source selection, fallback rules, and stale-data behavior;
  • transaction simulation policy;
  • alert thresholds for indexer lag, RPC error rate, and feed freshness;
  • the mapping between a business metric and the onchain state that proves it.

External teams can accelerate delivery. They cannot own the definition of correctness without becoming a permanent protocol dependency.

This matters in dapp development outsourcing contracts. A vendor can build the dashboard, wire the wallet, deploy the subgraph, and configure the RPC endpoints. Fine. But require an operational handover that includes environment variables, deployment keys or custody boundaries, indexer manifests, ABI versioning, endpoint quotas, and runbooks for degraded service. Otherwise the “service” is a black box with a monthly invoice.

Smart contract frameworks: Foundry wins the tight loop, Hardhat wins the familiar surface

Framework selection is one of the few infrastructure choices developers feel every hour. The performance delta compounds. A test suite that runs 2x to 5x faster changes behavior: more local tests, more fuzzing, fewer “I will run it in CI” shortcuts.

Foundry is Rust-based and runs Solidity tests natively. Hardhat is Node.js-based, built around JavaScript and TypeScript scripts, npm dependency management, and a broad plugin ecosystem. Neither is universally superior. They optimize different bottlenecks.

ParameterFoundryHardhat
Core development modelSolidity-native testing and scriptingJavaScript/TypeScript test and script workflow
Test and compile performanceTypically 2x to 5x faster than JavaScript-based alternativesSlower for many test-heavy workflows
Best fitContract-heavy teams optimizing iteration timeTeams with deep TypeScript tooling and plugin needs
Ecosystem shapeLean, contract-centric toolingLarger plugin ecosystem
Team onboardingStrong for Solidity-first engineersFamiliar to full-stack JavaScript teams
CI pressureLower wall-clock time for repeated test runsCan be acceptable, but grows with test suite size

The benchmark headline—Foundry running tests two to five times faster—is useful, but it is not the whole decision. Measure the workflow, not the framework logo.

A protocol team with 1,500 Solidity tests, fuzz campaigns, fork tests, and frequent contract revisions will feel Foundry’s speed immediately. The bottleneck is execution time. Cut it. A frontend-heavy team already running a mature TypeScript monorepo may value Hardhat’s integration surface more than raw local test throughput. The bottleneck is coordination cost. Do not create a second language island just to win a benchmark.

The practical split that works

Many production teams should stop treating this as an exclusive choice.

Use Foundry where it is strongest:

  • fast Solidity unit tests;
  • fuzzing and invariant-focused contract work;
  • deployment scripts close to the contract code;
  • fork-based reproductions of state-dependent bugs;
  • CI lanes where wall-clock minutes translate directly into cost and developer queue time.

Use Hardhat where it already owns the workflow:

  • TypeScript-heavy integration tests;
  • plugin-dependent deployment or verification pipelines;
  • frontend-adjacent scripting;
  • teams whose operational tooling is deeply tied to Node.js and npm.

The failure mode is not “using both.” The failure mode is duplicating deployment logic until the two paths produce different bytecode inputs, constructor arguments, or network configuration. One source of release truth. One artifact policy. One clearly owned deployment path.

Framework speed is not a vanity metric. It determines how much adversarial testing fits inside a normal engineering day.

For node operators and CI owners, profile test execution before buying larger runners. A 4x faster suite can be more valuable than another parallelism tier, especially when fork tests hit external endpoints. Local execution speed is cheap. Remote RPC dependency is not.

Managed RPC node economics: request count is the wrong denominator

The billing model for node access has changed the conversation. “We make ten million requests” tells you almost nothing if providers meter request complexity differently.

Alchemy uses Compute Units, or CUs. Its free tier includes 30 million CUs per month. On pay-as-you-go, the first 300 million CUs are priced at $0.45 per million CUs. QuickNode uses API Credits and packages them by plan: Build includes 80 million credits for $49 per month, Accelerate includes 450 million for $249, and Scale includes 950 million for $499.

These are not interchangeable units. Do not compare them as though one CU equals one API Credit or one JSON-RPC call. The operational question is what your real method mix consumes.

Provider modelEntry reference pointMetering unitWhat to model before committing
Alchemy30M CUs/month free tierCompute UnitsMethod weights, burst shape, archive reads, trace/debug usage
Alchemy pay-as-you-go$0.45 per 1M CUs up to 300M CUsCompute UnitsMarginal CU consumption after free allocation
QuickNode Build$49/month for 80M creditsAPI CreditsBaseline application traffic and developer environments
QuickNode Accelerate$249/month for 450M creditsAPI CreditsGrowth-stage traffic and multi-service usage
QuickNode Scale$499/month for 950M creditsAPI CreditsSustained production consumption and quota headroom

A low-cost plan can become expensive when the application quietly shifts from lightweight state reads to heavier methods. Archive queries, transaction traces, debug endpoints, broad log scans, aggressive polling, and poorly bounded backfills all change the consumption curve.

That is why raw request count fails as a planning metric. Two dapps can both make 20 million calls per month. One reads a few current balances and block headers. The other scans historical logs across dozens of contracts, runs simulation calls, and refreshes data on every connected client. Same count. Different bill. Different p95 latency. Different failure rate under load.

Build an RPC ledger before selecting a provider

Pull one week of production-like traffic and classify it. No guesses. No blended “average request” fiction.

Track at least:

  • method name and chain;
  • request frequency by minute, not just monthly total;
  • payload size where relevant;
  • response size;
  • p50, p95, and p99 latency;
  • error codes and timeout rate;
  • retry count;
  • whether the call is user-blocking;
  • whether the call can be served by an indexer, cache, or multicall;
  • whether it needs archive state, traces, pending state, or WebSocket delivery.

Then split calls into three pools.

Interactive reads are user-blocking: wallet balances, quote inputs, allowance state, transaction simulation. Optimize latency and availability. Use bounded retries. A delayed response here becomes a conversion problem.

Background reads are refreshable: portfolio history, analytics, token activity, backfills. Queue them. Batch them. Cache aggressively. Do not let them compete with transaction construction.

Operational reads support monitoring and incident response: event verification, trace analysis, state investigation. They may be expensive, but they are intermittent. Budget separately so an incident does not collide with the product quota.

This is also where a secondary endpoint earns its cost. Not as an always-on duplicate for every request. As a tested failover path for critical methods and chains. Failover that has never been exercised is documentation, not resilience.

For oracle-consuming contracts, add a separate monitor for the data path. RPC health does not prove feed health. Track the latest onchain round or update timestamp, the deviation from an independent reference where the protocol permits it, and the age of the last successful application read. Three clocks. One user-visible price. They will drift independently.

Post-Hosted Service reality: indexing is now a production decision

The Graph Hosted Service was fully deprecated in 2026. That removes a familiar default for teams that built subgraphs early and left them untouched.

The migration decision is not merely “where do we host the same manifest?” It is a choice about network coverage, indexing operations, query reliability, deployment workflow, and the cost of keeping application state queryable as contracts evolve.

Goldsky offers a backwards-compatible subgraph indexing path across more than 140 networks. It supports migration from The Graph through a CLI-driven flow using an IPFS hash. That is operationally attractive for teams whose existing subgraph schema and mappings are stable. Goldsky also advertises 99.9%+ indexing uptime, but availability should be measured against your own endpoint behavior, sync lag, and query pattern—not accepted as a substitute for monitoring.

The Graph Network remains relevant when decentralized indexing participation and the ecosystem’s native deployment model align with the application’s needs. Managed alternatives such as Goldsky, Ormi, and SubQuery can reduce operational drag where predictable hosted behavior matters more than running every component yourself.

Do not migrate stale assumptions

A subgraph migration can preserve a flawed data model perfectly. That is not success.

Before moving anything, inspect these pressure points:

1. Schema versioning. Contract upgrades, newly emitted events, and changed entity relationships must be represented explicitly. A frontend reading an old schema can look healthy while silently omitting new state.

2. Start block selection. Indexing from unnecessarily early blocks increases catch-up time and cost. Starting too late creates permanent holes. Establish the exact deployment block for every indexed contract.

3. Reorg behavior. Your UI should tolerate temporary reversals. Do not present an indexed event as irreversible finality simply because it appeared in a query response.

4. Backfill load. Historical queries can dominate indexing workload. Separate product dashboards from internal analytics where possible.

5. Lag instrumentation. Record the indexed block, chain head, and block delta. “The API returned 200” is not an indexing health metric.

6. Fallback reads. For positions, collateral, and transaction-critical values, maintain a direct contract-read path. The indexer is optimized for retrieval. The chain remains the authority.

The biggest mistake after the Hosted Service shutdown is treating migration as a one-time infrastructure ticket. It is a production ownership transfer. Someone needs to own sync lag at 03:00, schema rollouts after a contract upgrade, and query behavior during traffic spikes.

Frontend integration: Ethers.js for separation, Web3.js for compatibility

The browser layer is where infrastructure choices become visible. A wallet connection error, a chain mismatch, or an RPC timeout does not look like middleware to the user. It looks like “the app is broken.”

Ethers.js and Web3.js remain primary JavaScript libraries for connecting applications to blockchain networks. Ethers.js has a particularly useful architectural split: provider connections are separate from wallet signing. That distinction keeps read operations, signer permissions, and transport configuration from collapsing into one opaque client object.

For most scalable dapps, that separation is worth preserving.

Use a read-only provider for general state access. Use a signer only when a user initiates an action. Keep the provider selection explicit. A wallet-injected provider is not automatically the best source for application reads, especially when you need consistent chain access, rate-limit control, or fallback endpoints.

A practical frontend request path looks like this:

  • Query indexed data for tables, history, search, and broad portfolio views.
  • Read contract state directly before constructing a critical transaction.
  • Simulate where the transaction flow supports it.
  • Request a wallet signature only after parameters are fixed and user-visible.
  • Submit through the chosen transport path.
  • Monitor the receipt and refresh state from chain truth, not merely optimistic UI assumptions.

The technical distinction matters most around pricing and risk. If a swap quote is derived from an oracle, include the price timestamp and the acceptable staleness window in the application logic. If the displayed quote came through an indexer, do not silently use it as the final transaction parameter without a live contract or router read. TWAP and VWAP are not decorative labels. They are time-bound data constructions. Their observation window and update point matter.

Reduce gas overhead outside the contract first

Developers often reach for contract optimization when the application layer is wasting calls. Fix the request graph before shaving a few opcodes.

A few durable moves:

  • batch compatible reads with multicall rather than serializing dozens of RPC calls;
  • debounce quote requests driven by user input;
  • cache immutable metadata such as token decimals and symbols;
  • avoid polling every component independently;
  • subscribe via WebSockets only where event push genuinely replaces expensive polling;
  • move historical tables and analytics to indexed queries;
  • cap log query ranges during backfills;
  • separate “refresh now” actions from automatic background refresh loops.

This reduces RPC spend, frontend jitter, and provider quota pressure at the same time. It also makes actual gas overhead easier to see. When the client stops making redundant calls, you can focus on transaction calldata, storage writes, and execution paths rather than debugging a noisy interface.

The stack should be optimized as a data pipeline, not a vendor list

Web3 development services are not a shopping cart. They are a latency budget and a correctness budget spread across six layers.

Start with the contract and the data it consumes. Map what must be current, what can be indexed, what can be cached, and what must survive provider degradation. Then choose the framework that matches the team’s dominant engineering loop. Foundry is the clear pressure-release valve for Solidity-heavy test cycles; Hardhat remains efficient where TypeScript and plugins are the center of gravity.

For RPC, model weighted usage. CUs and API Credits are consumption systems, not cosmetic billing labels. Profile methods, isolate interactive traffic, and test fallback routes before a traffic spike does it for you.

For indexing, the Hosted Service era is over. Treat migration as an operational design decision. Measure block lag. Version schemas. Keep direct reads for values that can move money.

And for node operators: export the method-level logs, calculate p95 and p99 by endpoint, tag every retry, and put quota alerts below the point where users notice. The fastest infrastructure optimization is usually not a new provider. It is deleting the calls your application never needed to make.

FAQ

How should I choose between Foundry and Hardhat for my project?
Choose Foundry if your team prioritizes fast Solidity-native testing, fuzzing, and contract-heavy iteration. Choose Hardhat if your workflow is deeply integrated with TypeScript, npm, and existing plugin ecosystems.
Why is request count a poor metric for planning RPC costs?
Different RPC methods have varying weights and complexities, such as archive reads or trace calls, which consume compute units or credits at different rates. Two applications with identical request counts can have vastly different costs and performance profiles based on the specific methods they call.
What is the best way to handle indexing lag in a Web3 application?
Do not treat indexed data as instant finality. Maintain a direct contract-read path for critical values like collateral ratios or balances, and ensure the UI explicitly handles or discloses potential indexing lag.
What should be kept in-house versus outsourced in Web3 development?
Keep protocol-specific logic like contract ABIs, event schemas, oracle selection, and transaction simulation policies in-house. Outsource commodity tasks like node access, broad chain coverage, and infrastructure uptime.
How can I reduce RPC costs without changing providers?
Optimize your request graph by batching reads with multicall, caching immutable metadata, debouncing user-input-driven requests, and moving historical data queries to an indexing layer.