Posted in Cloud & Infrastructure, Engineering

Edge Computing in 2026: Cloudflare Workers vs Vercel vs Deno Deploy, Where Your Code Actually Runs and What It Costs

“Run your code at the edge” was the serverless pitch of the early 2020s: put logic close to users and cut latency. In 2026 the three platforms most associated with that pitch have taken noticeably different paths. We checked each one’s official documentation and pricing on October 28, 2026 to see where code actually runs today, what limits apply, and what it costs.

At a Glance

SpecCloudflare WorkersVercel FunctionsDeno Deploy
Where code runsCloudflare’s global network, across hundreds of locationsConfigurable regions on Fluid compute; edge runtime runs nearest the request2 regions on the new platform, plus self-hosted regions
RuntimeV8 isolatesNode.js (recommended) or Edge runtime (V8)Deno 2, with Node app support
Free tier100,000 requests/day, 10 ms CPU per invocationHobby: 1M invocations, 4 hrs Active CPU/month (non-commercial)1M requests, 10 hrs Active CPU/month
Entry paid plan$5/month minimumPro: $20/month with $20 usage creditPro: $20/month
Edge direction in 2026Edge-first by designRecommends migrating from Edge to Node.jsFewer regions than Deploy Classic, which shut down July 20, 2026

Short Verdict

If “edge” is the requirement, meaning code that runs near every user by default, Cloudflare Workers is the platform still built around it, with a $5 paid plan and CPU-time billing that does not charge for time spent waiting on network calls. Vercel now steers developers away from its Edge runtime and toward Node.js on Fluid compute, which favors running functions near your data rather than near your users. The new Deno Deploy runs in two regions, so it is better viewed as a serverless platform than an edge network. Pick based on where your data lives: if your database sits in one region, compute next to it usually beats compute next to the user.

What “Edge” Means Here

Edge computing means processing a request in a location close to the user instead of in one central region. It shortens the network round trip for work that does not need a central database, such as redirects, authentication checks, personalization from cookies, A/B test assignment, and caching logic. It helps much less when every request must read from a single-region database, because the edge function then makes its own long round trip to that database.

Cloudflare Workers

Workers run on Cloudflare’s global network, which the company describes as thousands of machines across hundreds of locations, and a request arriving at any Cloudflare data center can invoke your Worker. Instead of a container or virtual machine per function, each Worker runs in a V8 isolate inside an existing runtime process. Cloudflare says an isolate can start around a hundred times faster than a Node process in a container or VM and uses an order of magnitude less memory at startup, which is why Workers avoid the classic cold-start penalty. Isolates can be evicted at any time, so global mutable state should not be relied on.

PlanRequestsCPU timePrice
Free100,000/day10 ms per invocation$0
Paid (Standard)10M/month included, then $0.30 per million30M CPU-ms/month included, then $0.02 per million CPU-ms; up to 5 minutes CPU per request (30 s default)$5/month minimum

Cloudflare does not charge for duration, only CPU time, so a Worker that spends most of its time waiting on a fetch is billed only for the milliseconds it actually computes.

Vercel: From Edge Runtime to Fluid Compute

Vercel’s Edge runtime still exists and, by default, executes in the region closest to the incoming request. But Vercel’s own documentation now recommends migrating from Edge to Node.js “for improved performance and reliability,” notes that both runtimes run on Fluid compute with Active CPU pricing, and states that starting in Next.js 16.3, setting runtime = 'edge' is no longer supported. The Edge runtime also has real constraints: a subset of Web and Node.js APIs, no filesystem access, no eval, a requirement to begin responding within 25 seconds, and code size limits of 1 MB (Hobby), 2 MB (Pro), and 4 MB (Enterprise) after compression.

ResourceHobby (included)Pro (beyond included credit)
Active CPU4 hours/monthFrom $0.128/hour
Provisioned memory360 GB-hours/monthFrom $0.0106/GB-hour
Function invocations1M/monthFrom $0.60 per million

Hobby is for personal, non-commercial use and cannot buy extra usage. Pro costs $20 a month, includes $20 of usage credit, and is pay-as-you-go beyond it.

Deno Deploy: Rebuilt, and Fewer Regions

Deno rebuilt Deploy on a new execution environment using Deno 2.0 that runs both Deno and Node apps, with first-class support for Next.js, Astro, and SvelteKit. Its documentation lists 2 regions for the new platform, compared with 6 for Deploy Classic, plus the option of self-hosted regions. Deno announced that Deploy Classic and the subhosting v1 API would shut down on July 20, 2026.

PlanPriceRequests/monthActive CPUEgress
Free$01M10 hours20 GiB
Pro$20/month5M, then $2 per million50 hours, then $0.10/hour200 GiB, then $0.20/GiB
Builder$200/month25M, then $2 per million500 hours, then $0.10/hour2,000 GiB, then $0.20/GiB
EnterpriseCustomCustomCustomCustom; 99.95% SLA

Pros and Cons by Platform

  • Cloudflare Workers pros: genuinely global by default, isolate-based startup, cheap $5 entry plan, no charge for waiting time. Cons: isolate runtime is not full Node.js, and the free tier’s 10 ms CPU cap is tight for heavier work.
  • Vercel pros: tight integration with Next.js and Fluid compute, configurable regions near your data. Cons: Edge runtime is being de-emphasized and is unsupported in Next.js 16.3+, and Hobby is non-commercial only.
  • Deno Deploy pros: generous free CPU allowance, Deno and Node apps, self-hosted regions, clear usage pricing. Cons: only 2 managed regions on the new platform, and teams on Deploy Classic had to migrate.

Bottom Line

The industry has quietly split “edge” in two. Cloudflare Workers still runs your code near the user everywhere, which is ideal for request-level logic that does not need a central database. Vercel and Deno have moved toward regional serverless compute placed near your data, which suits typical database-backed apps better. Decide which latency you are actually fighting, user-to-server or server-to-database, and the platform choice follows.

Frequently Asked Questions

  • Is Vercel’s Edge runtime deprecated? Vercel recommends migrating from Edge to Node.js, and setting runtime = 'edge' is no longer supported starting in Next.js 16.3.
  • How much does Cloudflare Workers cost? Free for 100,000 requests a day; the paid plan starts at $5 a month with 10 million requests and 30 million CPU milliseconds included.
  • Is Deno Deploy an edge platform? The new Deno Deploy lists 2 managed regions, so it behaves more like regional serverless; Deploy Classic, which had 6 regions, shut down on July 20, 2026.
  • When does edge computing not help? When every request must reach a single-region database, since the edge function then adds its own long round trip.

Sources

Posted in Engineering

Unicode for Developers: Code Points, Grapheme Clusters, and Normalization Without the Bugs

Most string bugs that reach production come from one wrong assumption: that one “character” equals one unit of storage. It does not. A single letter can be one code point or two, a single emoji can be eight UTF-16 units, and two strings that look identical can fail an equality check. This deep dive explains the three layers you need to keep straight (code units, code points, and grapheme clusters), how normalization fixes the equality problem, and which built-in tools handle all of it correctly.

At a Glance

ConceptWhat it means
Code unitThe storage unit of an encoding; JavaScript’s length counts UTF-16 code units
Code pointA single Unicode value such as U+00F1; may take one or two UTF-16 units
Grapheme clusterWhat a user perceives as one character; may span several code points
NormalizationConverting text to a standard form (NFC, NFD, NFKC, NFKD) so equivalent strings compare equal
Governing specsUAX #29 (text segmentation) and UAX #15 (normalization forms)
Built-in tools (JavaScript)String.prototype.normalize() and Intl.Segmenter

Short Verdict

Store and transmit text as-is, normalize to NFC before comparing or indexing it, and use grapheme segmentation, not length or code point counts, whenever the result is shown to a person: truncation, cursor movement, character limits, and “reverse this string.” Use compatibility normalization (NFKC/NFKD) only for search and matching, never to rewrite what the user typed.

Layer 1 and 2: Code Units vs Code Points

Unicode assigns every character a code point, written like U+00F1. Encodings then store those code points as code units: UTF-8 uses 8-bit units, UTF-16 uses 16-bit units. JavaScript strings are UTF-16, so length counts 16-bit units, not characters. Code points above U+FFFF, which include most emoji, need two UTF-16 units each (a surrogate pair). Splitting a string in the middle of a surrogate pair produces broken text, which is why naive slice() truncation can corrupt emoji.

Layer 3: Grapheme Clusters

Unicode Standard Annex #29, the specification for text segmentation (its current revision covers Unicode 18.0.0), puts the core problem plainly: a single code point is often, but not always, the same as a basic unit of a writing system. What users see as one character is approximated by a grapheme cluster. A letter followed by a combining accent is one cluster made of two code points. A Hangul syllable can be one precomposed code point or a sequence of conjoining jamo. And per UAX #29, each emoji sequence in the recommended (RGI) emoji set is a single grapheme cluster, even when it is built from several emoji joined by zero-width joiners.

UAX #29 defines two kinds of clusters. Legacy grapheme clusters are a base character plus continuing marks. Extended grapheme clusters, the default, also absorb spacing combining marks such as many Indic vowel signs, and the annex recommends them over legacy clusters except where the legacy variant is specifically required. Two useful properties: cluster boundaries are the same whether text is in NFC or NFD, and clusters do not necessarily match what the font draws, since a ligature like “fi” may render as one glyph while still being two clusters.

In JavaScript, Intl.Segmenter implements this segmentation and is marked Baseline widely available on MDN, supported across browsers since April 2024. A family emoji built from three emoji and two zero-width joiners shows the gap between storage and perception:

const family = "\u{1F468}\u200D\u{1F469}\u200D\u{1F467}"; // man ZWJ woman ZWJ girl
console.log(family.length);            // 8 UTF-16 code units
console.log([...family].length);       // 5 code points

const seg = new Intl.Segmenter("en", { granularity: "grapheme" });
console.log([...seg.segment(family)].length); // 1 user-perceived character

The same API supports "word" and "sentence" granularity. That matters because, as UAX #29 notes, word boundaries are not restricted to whitespace and punctuation, and languages such as Chinese, Japanese, and Thai do not separate words with spaces at all, so split(" ") fails on them.

Normalization: Making Equal Strings Equal

The letter “ñ” can be stored as the single code point U+00F1 or as “n” (U+006E) followed by a combining tilde (U+0303). The two render identically, but a byte-for-byte comparison says they differ. Unicode calls them canonically equivalent: they represent the same abstract character and should look and behave the same. Normalization picks one standard representation so comparisons work.

FormWhat it doesUse it for
NFCCanonical decomposition, then canonical composition (composed form)The default for storage keys, comparison, and most text processing
NFDCanonical decomposition (decomposed form)Processing that wants base letters and marks separated, such as accent stripping
NFKCCompatibility decomposition, then canonical compositionSearch and matching, where “ff” should match “ff”
NFKDCompatibility decompositionSearch indexing that also wants marks separated
const a = "\u00F1";        // precomposed
const b = "\u006E\u0303";  // n + combining tilde
console.log(a === b);                                   // false
console.log(a.normalize("NFC") === b.normalize("NFC")); // true

const lig = "\uFB00";      // the "ff" ligature
console.log(lig.normalize("NFKC"));                     // "ff"

Compatibility equivalence is weaker than canonical equivalence: all canonically equivalent sequences are also compatible, but not the other way round. Compatible sequences should be treated alike in some applications but not necessarily all. MDN’s guidance captures the trade-off well: compatibility normalization suits search, because a user can find the ligature by typing “f”, but may not suit display, because it changes how the text looks. That is why you should normalize a copy for matching rather than overwrite what the user entered.

Common Bugs and Their Fixes

  • Character limits that reject valid input. A 20-character username limit enforced with length counts emoji as several characters. Count grapheme clusters for user-facing limits, and enforce a separate byte limit for storage.
  • Truncation that breaks emoji or accents. Cut at grapheme boundaries, not at a fixed code unit index.
  • Duplicate accounts or failed lookups. “Amélie” typed on two keyboards can produce two different code point sequences. Normalize to NFC before using text as a key.
  • String reversal that mangles text. Reverse the array of grapheme segments, not the code units.
  • Word counts that fail in some languages. Use word segmentation instead of splitting on spaces.

Bottom Line

Keep three layers in mind: code units for storage limits, code points for encoding logic, and grapheme clusters for anything a person sees. Normalize to NFC before comparing, reserve NFKC/NFKD for search, and lean on the platform: normalize() and Intl.Segmenter already implement the Unicode rules so you do not have to.

Frequently Asked Questions

  • Why is an emoji’s length more than 1 in JavaScript? length counts UTF-16 code units; emoji above U+FFFF take two units each, and joined sequences add zero-width joiners.
  • Which normalization form should I store? NFC is the usual choice for storage and comparison; it is also the default for normalize().
  • When should I use NFKC? For search and matching, not for display or for rewriting user input.
  • How do I count characters the way users see them? Use grapheme segmentation, such as Intl.Segmenter with granularity: "grapheme".

Sources

Posted in Engineering

CRDTs Explained: How Conflict-Free Replicated Data Types Keep Distributed Data in Sync

Collaborative editors, offline-first mobile apps, and multi-region databases all face the same problem: two copies of the same data get changed at the same time, and they have to end up identical without anyone losing work. Conflict-free replicated data types, or CRDTs, are the best-studied answer. This explainer covers what they guarantee, the two ways they are built, the classic examples, and the libraries most developers reach for today.

At a Glance

ConceptSummary
What a CRDT isA replicated data type whose copies can be updated independently and always merge to the same state
GuaranteeStrong eventual consistency: replicas that received the same updates are in the same state
Two designsState-based (CvRDT): ship and merge whole states; operation-based (CmRDT): ship commuting operations
Formalized inShapiro, Preguiça, Baquero, Zawirski, “Conflict-free Replicated Data Types” (SSS 2011)
Popular librariesAutomerge (JavaScript/Rust) and Yjs (JavaScript)
Best forCollaboration, offline-first apps, and multi-replica systems that must accept writes anywhere

Short Verdict

Reach for CRDTs when every replica must accept writes without waiting for the others, such as a document edited offline or a counter updated in several regions. You trade some storage overhead and a constrained set of data types for the ability to merge automatically, with no conflict-resolution code and no rollbacks. If your data needs strict invariants that span many records, such as “this account balance must never go negative,” a CRDT alone is the wrong tool.

The Guarantee: Strong Eventual Consistency

Plain eventual consistency only promises that replicas will agree at some point after updates stop arriving, and usually needs some way to arbitrate conflicts or roll back. The 2011 paper by Marc Shapiro, Nuno Preguiça, Carlos Baquero, and Marek Zawirski formalized a stronger property, strong eventual consistency (SEC): any two replicas that have delivered the same set of updates are in equivalent states, at all times. Because convergence is built into the data type, no rollback or arbitration step is needed. The paper also shows that replicas of a CRDT converge in a self-stabilizing way despite any number of failures.

Two Ways to Build a CRDT

State-based (CvRDT)Operation-based (CmRDT)
What replicas sendTheir full stateIndividual update operations
Mathematical requirementStates form a join semilattice; merge computes the least upper bound; updates only move the state upwardConcurrent operations must commute
Network requirementVery little: states can arrive late, twice, or out of orderOperations must be delivered in causal order
Trade-offSimple delivery, but sending whole states can be heavySmall messages, but needs a reliable causal delivery layer

The paper proves both designs give strong eventual consistency and that each can emulate the other, so the choice is an engineering trade-off about bandwidth and delivery guarantees rather than about correctness.

Classic Examples

  • Increment-only counter. Each replica keeps a vector with one slot per replica and only increments its own slot. Merging takes the per-slot maximum, and the counter’s value is the sum. This is what most later writing calls a G-Counter.
  • Increment/decrement counter. Two increment-only counters, one for increments and one for decrements; the value is the difference. Commonly called a PN-Counter.
  • Add-only set. Sets merge by union, so adds can never conflict. Commonly called a G-Set.
  • Add/remove set with tombstones. The paper’s U-Set pairs an add set with a remove set and assumes each element is added only once; the familiar 2P-Set works the same way, and the trade-off is that a removed element cannot come back.
  • Directed graph. The paper’s op-based graph tags vertices and arcs with unique IDs; if one replica removes a vertex while another adds an arc to it, the removal wins.

Libraries You Can Use Today

Automerge is a library of CRDT data structures for collaborative apps. Each user keeps a local copy that can be edited offline and saved to disk, and changes merge automatically when devices reconnect. It is written in Rust, compiles to WebAssembly for browsers, runs on Node.js, exposes a C API for platforms without a JavaScript engine, and is network-agnostic: it can sync over WebSockets, peer-to-peer WebRTC, or even a file passed by email. The companion automerge-repo library provides ready-made networking and storage.

Yjs exposes CRDTs as shared types, similar to familiar maps and arrays, that many users can edit at once and that emit change events. It also makes no assumptions about the network: as long as every update eventually arrives, in any order, documents converge. It offers network adapters for WebSocket, WebRTC, and Hyper, persistence providers, and bindings for editors including ProseMirror, Tiptap, Monaco, Quill, and CodeMirror.

Pros

Writes never wait on other replicas, which makes offline editing and multi-region writes straightforward. Merges are automatic and deterministic, so there is no conflict-resolution code to write or test. Convergence is a mathematical property of the type, not a hope about timing, and it holds even when messages are delayed, duplicated, or reordered (for state-based designs).

Cons

Metadata such as per-replica vectors and tombstones grows over time and needs compaction or garbage collection. The automatic merge result is consistent but not always what a user intended, so applications still need to design sensible semantics. And CRDTs cannot enforce global invariants on their own, such as uniqueness across records or a minimum balance, which still require coordination.

Bottom Line

CRDTs turn “merge conflicts” into a property of the data type rather than a problem for application code. They are the right default for collaborative and offline-first features, and libraries like Automerge and Yjs make them practical without implementing the math yourself. Pair them with coordination only where you truly need global invariants.

Frequently Asked Questions

  • What does CRDT stand for? Conflict-free replicated data type.
  • What is strong eventual consistency? A guarantee that any replicas which have received the same updates are in the same state, with no rollbacks needed.
  • State-based or operation-based? State-based tolerates unreliable delivery but sends more data; operation-based sends small messages but requires causal delivery. Both converge.
  • Do I need a server? No. Libraries like Automerge and Yjs work peer-to-peer or through a server, because convergence does not depend on a central authority.

Sources

Posted in Engineering, software

GitHub Copilot Review: Plans, AI Credits, and Which Tier a Developer Actually Needs in 2026

Get GitHub Copilot: Visit the official GitHub Copilot plans page →

At a Glance

SpecValue
Free planYes — 2,000 inline suggestions/month, limited chat and agent use
Starting paid pricePro, $10/month
Individual tiersFree, Pro ($10), Pro+ ($39), Max ($100) per month
Business / EnterpriseNot priced on the plans page — contact sales
Usage unitGitHub AI Credits (1 credit = $0.01)
Best forDevelopers already on GitHub who want AI completions, chat, and an agent that opens pull requests

Short Verdict

GitHub Copilot’s free tier is a genuine trial of the product, with 2,000 inline suggestions a month and limited chat. For anyone coding most days, Pro at $10 a month is the sensible starting point: it removes the suggestion cap and adds code review and the cloud agent that turns assigned issues into pull requests. Pro+ and Max mostly buy a bigger monthly pool of AI credits plus the ability to hand tasks to third-party coding agents, so they only make sense if you regularly run out of credits on Pro. The big change to understand in 2026 is that usage is now measured in dollar-denominated AI credits rather than a simple request count.

What GitHub Copilot Is

GitHub Copilot is GitHub’s AI coding assistant. It suggests code inline as you type, answers questions in a chat panel, runs an agent mode that can make multi-file changes, works from the command line through the Copilot CLI, and on paid plans can act as a cloud agent: you assign it an issue on GitHub and it works in the background and opens a pull request for you to review.

Pricing Breakdown

PlanPrice/monthBase creditsFlex allotmentTotal monthly credit valueInline suggestions
Free$0Limited chat and agent usage2,000/month
Pro$10$10$5$15Unlimited
Pro+$39$39$31$70Unlimited
Max$100$100$100$200Unlimited
Business / EnterpriseContact sales; not priced on the plans page

GitHub now meters chat, agent, and other advanced features in GitHub AI Credits, with one credit worth $0.01. Each paid plan comes with base credits equal to its price plus a flex allotment on top, so Pro effectively includes $15 of monthly usage, Pro+ $70, and Max $200. The plans page we checked did not list annual pricing for any tier.

Features by Tier

The Free plan already includes the Copilot CLI, agent mode, MCP server support, and custom instructions, but not code review, the cloud agent, or app modernization. Pro adds Copilot code review on pull requests, the cloud agent, app modernization for Java and .NET projects, and support for repository instruction files. Pro+ and Max add delegation to third-party coding agents, such as Anthropic’s Claude and OpenAI Codex, which GitHub labels as a preview; beyond that, the two differ mainly in credit volume. Enterprise-grade security, IP indemnity, SAML SSO, usage metrics, and user management are not part of any individual plan and require Business or Enterprise. One caution: the plans page lists the same set of AI models across every tier but its FAQ says Free users get entry-level models, so check which models you can actually select before relying on a specific one.

Pros

The free tier is usable for evaluation and light coding without a credit card. Pro is inexpensive at $10 a month and includes the features that change day-to-day work: unlimited completions, PR code review, and a cloud agent that works directly inside GitHub issues and pull requests. Copilot sits inside the platform where many teams already host code, so there is no separate tool to connect. The credit system makes heavy usage possible on higher tiers without hard request caps.

Cons

Dollar-denominated credits are harder to predict than a flat request count, because how fast you spend them depends on which features and models you use. Business and Enterprise pricing is not published on the plans page, which makes team budgeting harder without a sales conversation. Third-party agent delegation is still a preview and is only on the two most expensive individual plans. The model-availability wording on the plans page is inconsistent, as noted above.

Who It’s a Good Fit For

Individual developers and freelancers who host their code on GitHub and want completions, chat, and an agent that can pick up issues and open pull requests. Pro covers most of them. Pro+ or Max fit developers who lean heavily on agents and regularly exhaust Pro’s $15 of monthly credit value.

Who Should Look Elsewhere

Teams that need SSO, usage metrics, or IP indemnity need Business or Enterprise and should get a quote before committing. Developers whose code lives outside GitHub lose the cloud agent and PR review integration, which are much of the paid plans’ value, so an editor-based AI assistant may fit better.

Bottom Line

Start on Free to see whether inline suggestions fit how you code, then move to Pro at $10 a month if you code regularly; it is the best value tier and includes the cloud agent and code review. Only step up to Pro+ or Max once Pro’s credit pool is clearly the bottleneck. Teams should treat Business and Enterprise as a sales conversation, since the plans page does not publish their prices.

Frequently Asked Questions

  • Is GitHub Copilot free? There is a free plan with 2,000 inline suggestions a month and limited chat and agent usage.
  • How much is Copilot Pro? $10 a month, which includes $15 of monthly AI credit value ($10 base plus a $5 flex allotment).
  • What is a GitHub AI Credit? The unit GitHub uses to meter advanced features; one credit equals $0.01.
  • How much do Business and Enterprise cost? The plans page does not list prices for them; GitHub directs teams to contact sales.

Sources