Skip to main content
shopify ecommerce16 Jun 2026·13 min read

"Shopify Functions vs Scripts: The WebAssembly Architecture Explained Correctly (With Official Limits)"

Dragoș-Adrian BuhoiuDragoș-Adrian BuhoiuFounder · Digital Ecosystem Architect
"Shopify Functions vs Scripts: The WebAssembly Architecture Explained Correctly (With Official Limits)"
FEATURED.IMG
"Shopify Functions vs Scripts: The WebAssembly Architecture Explained Correctly (With Official Limits)"
CONTENTS
01Shopify Functions vs Scripts: The WebAssembly Architecture Explained Correctly (With Official Limits)02TL;DR — the real difference in 60 seconds (compiled Wasm vs interpreted Ruby)03The 3-layer architecture: GraphQL input query → Wasm logic → declarative JSON output04The input → logic → output model (run.graphql → run.rs/run.js → "operations")05Function Targets inject code into Shopify's backend logic06WASM = compiled, not interpreted (why it matters compared to Scripts)07Dynamic Ruby doesn't compile directly to Wasm — why Shopify chose a static language08The security argument: "you cannot express anything malicious in Wasm"09Determinism by design: no random, no clock, no STDOUT/STDERR10No live external calls by default (nuanced network access)11Some Functions have network access under restrictions; unsupported endpoint ⇒ 502 Not supported12Purely declarative output (operations), not an HTTP response — no header manipulation13Exact official limits (table for citation)14Fixed limits15Dynamic limits (up to 200 line items)16Debunking viral myths (the rigor missing from the top-15)17Runtime is measured in INSTRUCTION COUNT (11M), NOT in milliseconds18"5ms" is a 2023 blog figure, qualified by Shopify as "machine-dependent and situational"19"100x faster than Scripts" does NOT appear in any official Shopify source20Recent optimizations: Wasm query API (May 2025) with just-in-time deserialization21Rust vs JavaScript: when to choose which (honestly, not "Rust always")22Availability and migration context (any plan vs Plus; Scripts sunset June 30, 2026)23The performance and sustainability angle

The real architecture (GraphQL → Wasm → JSON), exact official limits (instruction count, not ms), and the viral myths debunked (100x, 5ms).

Shopify Functions vs Scripts:The WebAssembly Architecture Explained Correctly (With Official Limits)

Last updated: June 16, 2026 | Sources: shopify.dev/docs — Functions, shopify.dev/docs/api/functions, shopify.engineering — WebAssembly, shopify.engineering — JavaScript in Wasm

Nearly every technical blog about Shopify Functions repeats the same numbers: "100x faster than Scripts", "under 5ms", "runs at the edge in milliseconds." None of these appear in current official documentation.

This teardown does what the SERP top-15 doesn't: explains the real architecture citing official sources directly, tabulates the exact limits, and debunks viral myths with factual rigor.

TL;DR — the real difference in 60 seconds (compiled Wasm vs interpreted Ruby)

CriterionScripts (EOL June 30, 2026)Functions
LanguageInterpreted RubyAny language → compiled to WebAssembly
RuntimeIsolated sandbox, full cart accessShopify edge infrastructure, declarative I/O
Data modelDirect access to Ruby objectsGraphQL input query → Wasm logic → JSON output
DeterminismNot explicitBy design: no random, no clock, no STDOUT
Runtime limitNot publicly documentedInstruction count (11M, dynamic)
Network accessN/A (Ruby sandbox)Nuanced: some Functions have it, with restrictions
AvailabilityShopify Plus onlyAny plan (public apps) / Plus (custom apps)

If you arrived here from our Scripts → Functions migration guide, you already know WHAT needs migrating. This article explains WHY the new architecture works.

The 3-layer architecture:GraphQL input query → Wasm logic → declarative JSON output

The input → logic → output model (run.graphql → run.rs/run.js → "operations")

Functions operate on a strict three-step model:

  1. Input: You define a GraphQL input query (run.graphql) that selects exactly the data you need from the Shopify context (cart, customer, metafields). Shopify runs this query before calling your Function and passes the resulting JSON as input.
  2. Logic: Your code (Rust, JavaScript, or any Wasm-compilable language) processes the JSON input and produces output.
  3. Output: A JSON document with a list of declarative "operations" that Shopify executes. You don't return a modified cart — you return instructions (e.g., "apply 10% discount on line X").

Official quote: "Before calling your target, Shopify runs its associated GraphQL query and passes the resulting JSON data to your target."

Source: shopify.dev/docs/api/functions.

Function Targets inject code into Shopify's backend logic

Functions are not external endpoints called via HTTP. They are Wasm modules that inject into Shopify's backend logic at specific target points: discount, delivery customization, payment customization, cart transform, validation.

Official quote: "Function Targets inject code into the backend logic of Shopify."

Source: shopify.dev/docs — Functions.

WASM = compiled, not interpreted (why it matters compared to Scripts)

Dynamic Ruby doesn't compile directly to Wasm — why Shopify chose a static language

Scripts used Ruby — an interpreted dynamic language. Ruby cannot be compiled directly to WebAssembly due to its dynamic nature (duck typing, eval, method_missing).

In the early implementation, Shopify chose AssemblyScript (a TypeScript subset compilable to Wasm) and then Rust. Official quote: "We decided to go with a statically compiled language and revisit the possibility of dynamic languages in the future."

Today, JavaScript is officially supported through the @shopify/shopify_function package (≥2.0.0), but Shopify recommends Rust (shopify_function crate ≥1.0.0) for superior performance: "Languages that compile directly to WebAssembly, such as Rust, perform better than dynamic languages, such as JavaScript."

Sources: shopify.engineering — WebAssembly (December 18, 2020) · shopify.dev/docs — programming languages.

The security argument:"you cannot express anything malicious in Wasm"

WebAssembly has a fundamental security advantage:

  • "You cannot express anything malicious in Wasm. You can only express manipulations of the virtual environment and use provided imports."
  • "Wasm executes within a sandboxed stack-based environment, relying upon explicit imports to allow communication with the host."

This means: a Function cannot access files, network, shared memory, or any host resource without Shopify explicitly permitting it through imports. The sandbox is architectural, not just by convention.

Source: shopify.engineering — WebAssembly (December 18, 2020).

Determinism by design:no random, no clock, no STDOUT/STDERR

Official quote: "Shopify doesn't allow nondeterminism in functions, which means that you can't use any randomizing or clock functionality in your functions."

Additionally, you cannot debug via STDOUT or STDERR — standard output is not captured. Debugging is done through documented error logs (max 1 kB, truncated).

This is a design restriction, not a bug. Shopify wants a Function to produce exactly the same output for the same input, regardless of execution time. Determinism guarantees reproducibility at scale.

Source: shopify.dev/docs/api/functions.

No live external calls by default (nuanced network access)

Some Functions have network access under restrictions; unsupported endpoint ⇒ 502 Not supported

The simplified myth: "Functions have no network access at all." The reality is nuanced:

Network access exists for certain Functions, under strict restrictions. Not every Function can make external calls, and not to any endpoint.

If you call an unsupported endpoint, the function runs locally but no actual request is sent — the target receives a response with status "502 — Not supported."

Source: shopify.dev/docs — network access.

Purely declarative output (operations), not an HTTP response — no header manipulation

A Function does not return an HTTP response. It returns a JSON document with a list of declarative operations. You don't manipulate request headers, set cookies, or perform redirects. Shopify processes the operations and applies them in the backend.

This is the fundamental difference from classic middleware or serverless functions. A Shopify Function is not an endpoint — it's a data transformation.

Exact official limits (table for citation)

Fixed limits

ResourceLimit
Compiled Wasm binarymax 256 kB
Linear runtime memory10,000 kB
Stack runtime memory512 kB
Written logs1 kB (truncated)

Dynamic limits (up to 200 line items)

ResourceLimit (≤200 line items)Above 200
Instruction count11 million instructionsScales proportionally
Function input128 kBScales proportionally
Function output20 kBScales proportionally

The instruction count limit is the most important — and the most poorly understood. It's not a time limit. It's a computational complexity limit for the Wasm module.

Source: shopify.dev/docs/api/functions.

Debunking viral myths (the rigor missing from the top-15)

Runtime is measured in INSTRUCTION COUNT (11M), NOT in milliseconds

Officially documented runtime errors include:

  • InstructionCountLimitExceededError
  • StackMemoryLimitExceededError
  • LinearMemoryLimitExceededError
  • OutputTooLargeError
  • InputSizeLimitExceededError

Notice: no ExecutionTimeLimitExceededError. The official limits page publishes no execution time threshold in milliseconds.

Sources: shopify.dev/docs — monitoring and errors · shopify.dev/docs/api/functions.

"5ms" is a 2023 blog figure, qualified by Shopify as "machine-dependent and situational"

The 5ms figure comes from a Shopify Engineering article from February 2023 about JavaScript in WebAssembly. The exact context: it was an internal development constraint, not a product limit.

Official quote: "The module must not run longer than 5ms" — but Shopify explicitly qualifies this as "a very machine-dependent and situational constraint."

It does not appear in current product documentation. It is not an official limit. It's a 2023 engineering figure that was virally adopted by blogs without context.

Source: shopify.engineering — JavaScript in WebAssembly for Shopify Functions (February 9, 2023).

"100x faster than Scripts" does NOT appear in any official Shopify source

We checked: shopify.dev, shopify.engineering, changelog.shopify.com, help.shopify.com. No official Shopify document contains the claim "100x faster" or any variation of it.

It's a marketing figure from third-party blogs. It may be plausible as an order of magnitude (compiled Wasm vs interpreted Ruby), but it is not an official Shopify claim and should not be cited as such.

Recent optimizations:Wasm query API (May 2025) with just-in-time deserialization

In May 2025, Shopify launched the Functions Wasm query API — an optimization enabling just-in-time deserialization: the Function reads only the fields actually used from the input, eliminating the overhead of including a full JSON parser in the binary.

Result: smaller functions (staying under the 256 kB limit) and more efficient execution (fewer instructions consumed on parsing).

If you have existing Functions with binaries approaching 256 kB, this is a concrete optimization path.

Source: shopify.dev/changelog — Functions Wasm query API (May 21, 2025).

Rust vs JavaScript:when to choose which (honestly, not "Rust always")

Shopify recommends Rust. But the honest recommendation is more nuanced:

Choose Rust when:

  • Your Functions are complex, approaching the 11M instruction limit
  • The binary must stay under 256 kB (Rust produces significantly smaller binaries)
  • Your team has Rust experience or is willing to invest in learning
  • Performance is critical (high line-item volumes)

Choose JavaScript when:

  • You have JS/TS developers who need to ship quickly
  • Business logic is simple (discount on tag, payment filter, shipping rename)
  • You iterate frequently and want a shorter development cycle
  • You're comfortable with the higher overhead (larger binary, more instructions)

It's not an absolute choice. It's a trade-off between performance and productivity. JS Functions run in production on millions of Shopify stores.

Source: shopify.dev/docs — programming languages.

Availability and migration context (any plan vs Plus; Scripts sunset June 30, 2026)

  • Any plan: can use public apps from the App Store that contain Functions.
  • Plus only: can run custom apps with Function APIs built with Shopify CLI.
  • Batch limit: a single Function API can execute up to 25 functions in a batch (increased from 5), for Payment/Delivery customizations, Cart/checkout validations, and Fulfillment constraints.

Scripts (Script Editor) were available exclusively on Shopify Plus. Sunset is June 30, 2026 — practical migration steps are detailed in our complete migration guide.

Sources: shopify.dev/docs/api/functions · shopify.dev/changelog — 25 functions limit (May 21, 2025).

The performance and sustainability angle

From the environmental engineering perspective we practice at Verdant Mindset:

Functions (WebAssembly on edge infra) vs Scripts (interpreted Ruby on server) = less CPU per execution. At the scale of Shopify checkouts (millions daily), this matters.

But we don't fabricate CO2 figures — we don't have official sources for the exact impact. What we know:

  • Compiled Wasm code is deterministically more efficient than interpreted Ruby.
  • Eliminating third-party apps with now-native functionality reduces storefront JS payload.
  • VM proof: TTFB of 0.21s on Shopify (Fitness Library) through eliminating redundant apps.

For the complete SEO + performance architecture on Shopify: our Shopify SEO architecture guide.

FAQ.PROTOCOL

Frequently Asked Questions

Scripts ran interpreted Ruby code in an isolated sandbox with direct cart object access. Functions run compiled WebAssembly modules on Shopify's edge infrastructure, with GraphQL input and declarative JSON output. The fundamental difference: Functions are deterministic by design and have no direct object access — everything passes through declarative queries.
Both are officially supported. Shopify recommends Rust for performance (smaller binaries, fewer instructions), but JavaScript is functional and widely used. The choice depends on team expertise and logic complexity.
The claim "100x faster" does not appear in any official Shopify source. It's a marketing figure from third-party blogs. Functions are likely significantly faster (compiled Wasm vs interpreted Ruby), but Shopify does not publish official performance comparisons.
The current official limit is expressed in instruction count: 11 million Wasm instructions (for up to 200 line items, scaling proportionally above). There is no published limit in milliseconds. The "5ms" figure is an internal engineering constraint from 2023, explicitly qualified by Shopify as "machine-dependent and situational."
Nuanced. Certain Functions have network access under strict restrictions. Not all Functions can make external calls, and not to any endpoint. Unsupported endpoints return status "502 — Not supported."
Compiled Wasm binary: max 256 kB. Linear runtime memory: 10,000 kB. Stack memory: 512 kB. Logs: 1 kB (truncated). Input: 128 kB (dynamic). Output: 20 kB (dynamic). Instruction count: 11M (dynamic). Dynamic limits scale proportionally above 200 line items.
Ruby is a dynamic language that cannot be compiled directly to Wasm. Shopify chose WebAssembly for three reasons: (1) determinism — same input produces same output, (2) security — "you cannot express anything malicious in Wasm," stack-based sandbox with explicit imports, (3) performance — natively compiled code vs interpreted. --- Last updated: June 16, 2026 Official sources used: shopify.dev/docs — Functions · shopify.dev/docs/api/functions · shopify.engineering — WebAssembly · shopify.engineering — JavaScript in Wasm · shopify.dev/changelog — Wasm query API · shopify.dev/docs — network access · shopify.dev/docs — monitoring and errors Want a technical audit of your Shopify store? Our team builds sustainable Shopify ecosystems. ```json { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Shopify Functions vs Scripts: The WebAssembly Architecture Explained Correctly (With Official Limits)", "description": "The real architecture (GraphQL input → Wasm → JSON output), exact official limits (instruction count, not ms), debunking viral myths (100x, 5ms). Official sources cited.", "datePublished": "2026-06-16", "dateModified": "2026-06-16", "author": { "@type": "Organization", "name": "Verdant Mindset", "url": "https://verdantmindset.com" }, "publisher": { "@type": "Organization", "name": "Verdant Mindset", "url": "https://verdantmindset.com" }, "inLanguage": "en", "mainEntityOfPage": "https://verdantmindset.com/en/resources/shopify-functions-vs-scripts" } ``` ```json { "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [ { "@type": "Question", "name": "What's the architectural difference between Shopify Functions and Scripts?", "acceptedAnswer": { "@type": "Answer", "text": "Scripts ran interpreted Ruby in an isolated sandbox with direct cart access. Functions run compiled WebAssembly on Shopify's edge infrastructure with GraphQL input and declarative JSON output." } }, { "@type": "Question", "name": "What language do you write Shopify Functions in: Rust or JavaScript?", "acceptedAnswer": { "@type": "Answer", "text": "Both are officially supported. Shopify recommends Rust for performance, but JavaScript is functional and widely used." } }, { "@type": "Question", "name": "Are Shopify Functions 100x faster than Scripts?", "acceptedAnswer": { "@type": "Answer", "text": "The claim 100x faster does not appear in any official Shopify source. It is a marketing figure from third-party blogs." } }, { "@type": "Question", "name": "What's the real runtime limit of a Shopify Function?", "acceptedAnswer": { "@type": "Answer", "text": "The official limit is instruction count: 11 million Wasm instructions. There is no published limit in milliseconds." } }, { "@type": "Question", "name": "Can I make external calls from a Shopify Function?", "acceptedAnswer": { "@type": "Answer", "text": "Nuanced. Certain Functions have network access under strict restrictions. Unsupported endpoints return 502 Not supported." } }, { "@type": "Question", "name": "What are the official size limits for a Shopify Function?", "acceptedAnswer": { "@type": "Answer", "text": "Wasm binary: max 256 kB. Linear memory: 10,000 kB. Stack: 512 kB. Logs: 1 kB. Input: 128 kB. Output: 20 kB. Instruction count: 11M. Dynamic limits scale above 200 line items." } }, { "@type": "Question", "name": "Why does Shopify use WebAssembly instead of Ruby?", "acceptedAnswer": { "@type": "Answer", "text": "Ruby is dynamic and cannot compile directly to Wasm. Shopify chose WebAssembly for determinism, security (sandbox with explicit imports), and performance." } } ] } ```

Digital engineering notes

SEO, AEO, automation — the essentials, every ~2 weeks. No spam.

Unsubscribe anytime. Privacy

Related Articles

FREE AUDIT · 24–48H

See exactly where you stand — no promises.

We run your site’s real data — speed, indexation, visibility in Google and AI search — and send you a concrete report.

✓ YES

  • Concrete, prioritised issues
  • Manually verified, not a tool
  • No card, no strings

✕ NO

  • “#1 guaranteed in 7 days”
  • Generic AI-spat report
  • Aggressive sales call
Get the free audit →
WhatsApp direct