Muse Spark 1.3 Is Fast. The 21x-Cheaper Version Has a Catch.

Published:

Meta’s new coding model is fast, unusually inexpensive, and comes in two versions with one consequential difference: the Standard route does not train on your work; the Contributor route can.

There is a version of this story that is just another benchmark roundup. This is not that story.

We put Meta’s Muse Spark 1.3 through the work we use to evaluate models at Chat-O: multi-file changes, debugging sessions, and test runs with OpenCode. One of those changes was making new chats start with a useful Chat Room by default—the Skeptic, Optimist, and Researcher—while letting every person replace that trio or start solo. That turns out to cross database state, authorization, LiveView components, the new-chat lifecycle, and tests. It is exactly the kind of work on which a coding model earns its keep.

Then we found the interesting part. The same model is sold two ways. One is already aggressively priced. The other is up to 21x cheaper—and the discount is paid for with permission to use your prompts and completions to improve future Meta models.

That is a real choice, clearly named. It is also a choice people should make with their eyes open.

What we saw

Muse Spark 1.3 feels built for an engineering loop rather than a one-off answer. It stays on task across tool calls, handles a large working set, and is comfortable with the unglamorous work: following a failing test, changing several files, then checking the result.

The experience is closer to handing a clear ticket to a quick junior engineer than prompting a chatbot: still review the work, but spend less time pulling it back to the point.

It is especially comfortable with the Elixir/Phoenix patterns in this app: tracing the boundary between persisted state, a LiveView component, and the first render of a new chat—then suggesting the smallest coherent change instead of a rewrite. We are evaluating it as a possible default coding model for our OpenCode Go workflow, but that decision will come from more completed tasks—not a benchmark chart.

Case study: making Chat Rooms the useful default

Chat Rooms work best when people arrive with a few thoughtful perspectives already in the room. But a “default” is not just three hard-coded names. It has to work for a new account, a person who has made custom personas, a person who wants no room at all, and a person who has deleted one of their old personas.

We did not hand Muse a database schema or a checklist of files to change. The starting point was the product request: make a useful Chat Room the default for new chats, let people choose their own roster in Settings, and do not break existing rooms. Through OpenCode, it had to trace the existing room flow, find where a new chat is initialized, recognize that a per-user preference needed durable storage, and preserve the authorization boundary around personas.

That investigation led to the shape of the implementation: a user-level setting, one resolver shared by Settings and chat startup, explicit semantics for an untouched versus empty selection, and regression tests at the authorization boundary. The finished feature touched eight files and added 211 lines across the application. We are not publishing our full repository diff, but the design is worth showing because it is the kind of detail that makes a feature dependable rather than merely demoable.

The product contract came first

The key design decision was to distinguish three states, not two:

Stored value Meaning
nil Use the platform default: Skeptic, Optimist, Researcher
[] Start a new chat solo—an explicit preference, not a missing setting
[persona_id, ...] Start with this person’s saved, authorized selection

That distinction avoids a common bug: treating an empty selection as “not configured,” then silently re-adding personas the person intentionally removed.

A small database change with important semantics

The setting lives with the user, not in browser storage and not on an individual chat session. That means it survives devices and applies to every fresh chat.

alter table(:users) do
  add :default_room_persona_ids, {:array, :binary_id}
end

The application-level resolver owns the behavior. On an untouched account it maps the three built-in titles to their current IDs; on a saved selection it returns only persona IDs that the account is allowed to use.

default_room_persona_ids(user)

The tiny public API matters more than the storage detail. Chat startup and Settings call the same resolver, so they cannot gradually develop two different definitions of “default room.”

Settings is a real control, not a hidden preference

The Settings page now lists the available personas as checkboxes, labels built-in characters, and explains the solo option plainly: uncheck everything to start alone. Submitting the form sends the selection through the LiveView component to the account layer, which persists it with a dedicated changeset.

This particular feature did not need a bespoke JavaScript state machine. The interactive HTML, validation boundary, and update flow are handled by Phoenix LiveView. That is an advantage: less duplicated client state, and one server-side source of truth for the selection.

The new-chat lifecycle is where it can quietly go wrong

Saving a setting is the easy part. A new chat must actually start in room mode with the saved roster, while opening an existing chat must not accidentally overwrite its history.

The Chat LiveView resolves the default when it mounts, then uses it to set both of the things the room pipeline needs:

room_mode: default_room_ids != []
room_selected_ids: default_room_ids

It repeats that resolution when the route becomes a fresh chat. That reset is important. Without it, a LiveView that had previously displayed another session could retain stale room state, or a newly saved setting would not take effect until a full browser reload.

Defaults cannot become an authorization bypass

Persona IDs are user-controlled input, even when they came from our own Settings page. The resolver therefore filters every saved ID through the same authorization boundary used by Chat Rooms: global personas and the person’s own personas survive; deleted, malformed, or somebody else’s personas are dropped.

That gives us a safe behavior for awkward but normal cases:

  • A deleted custom persona does not break new chat creation.
  • A stale ID does not appear in the roster.
  • A person cannot save another account’s persona ID and cause it to appear in their room.
  • The intentionally empty list still means solo mode.

The proof is in the tests, not the demo

The regression tests cover the platform trio and preserve their order, a saved custom default, removal of a foreign persona from a saved list, and the explicit empty-list/solo choice. That is the part we care about when evaluating a coding model: not whether it can produce a convincing UI, but whether it helps carry an apparently small product request across data modeling, server-side safety, rendering, navigation, and verification.

Muse was useful here because it stayed oriented across those layers. It could discuss the migration and state semantics, then come back to the LiveView initialization and test boundary without treating them as unrelated tickets. That is a much more meaningful signal for us than asking it to solve a toy algorithm.

Meta reports a 1-million-token context window and, compared with Spark 1.2, about 20% fewer tool calls and 25% fewer tokens for comparable work. Those are vendor-reported numbers, not an independent head-to-head; they are nevertheless directionally consistent with what we saw in agentic coding tasks. Meta’s launch note

The numbers, with the right label

The following is Meta’s comparison card for its maximum reasoning tier—not an independent leaderboard. It is useful context, especially for coding and long-context work, but it is not a substitute for trying a model on the work you actually do.

Benchmark Muse Spark 1.3 GPT-5.6 Sol Claude Opus 5
DeepSWE v1.1 (long-horizon coding) 75.4 73.0 74.0
Terminal-Bench 2.1 (terminal coding) 88.8 (tied) 88.8 (tied) 86.7
SWEAtlas CodeBase QnA 59.4 53.5 52.7
MRCR 512K to 1M (long-context retrieval) 98.1 73.8 n/a
GDPVal-AA v2 (knowledge work) 1754 1710 1824
OSWorld 2.0 (computer use) 66.9 62.7 68.3

The sensible reading is not “it wins everything.” It does not. It looks especially compelling for coding, tool use, and long-context tasks; other models remain stronger choices for some general-agent and browsing work.

One model, two data deals

This is the part worth understanding before you point it at a repository.

Route Input / 1M Output / 1M Data-use term
Standard $1.25 $4.25 Prompts and completions are not used to train Meta models
Contributor $0.10 $0.20 You permit prompts and completions to be used to improve/train future Meta models

Standard is already a strong value. Contributor is 12.5x cheaper on input and a little over 21x cheaper on output. That is not a coupon. It is a different agreement.

Meta is unusually direct about the distinction: Standard API content is not used to train Meta models, while the Contributor route trades a lower price for permission to use the work you send. Read the current terms before using Contributor with anything private, proprietary, or subject to a customer commitment. Meta Model API

The practical rule is simple:

  • Standard is a compelling option when no-training terms fit your policy.
  • Contributor is for disposable experiments, public material, or work you are explicitly comfortable contributing to model improvement.
  • Neither label means “zero retention.” Training, logging, and retention are separate questions.

Why High Privacy still says no

This is where the distinction matters for Chat-O.

Our High Privacy mode requires zero-data-retention (ZDR) routing for each request. ZDR means the provider does not store the request; it is stricter than a promise not to train on it. OpenRouter treats the two controls separately for exactly this reason. How OpenRouter’s ZDR filtering works

We tested the Standard route at meta/muse-spark-1.3 with ZDR enforced. OpenRouter returned no matching endpoint. The available route is no-training, but it carries a 30-day retention policy. That is a respectable and clearly different policy—not one we should silently describe as High Privacy.

So the honest product rule is straightforward:

  • With High Privacy on, Muse Spark 1.3 is excluded because it has no qualifying ZDR endpoint.
  • With Relaxed privacy selected, a product can offer the Standard route with a clear no-training / 30-day-retention disclosure.
  • The Contributor route should never be presented as a harmless cheaper toggle. It changes the data-use agreement.

That is better than pretending every model has the same privacy properties. People should be able to choose performance, price, and data handling deliberately.

The price is the headline

Against models we regularly evaluate, Standard Spark is cheap enough to change which tasks are practical to run:

Model Input / 1M Output / 1M
Muse Spark 1.3 Standard $1.25 $4.25
Claude Sonnet 5 $2.00 $10.00
GPT-5.6 Sol $2.00 $10.00
Claude Opus 5 $5.00 $25.00
Gemini 3.8 Flash $0.75 $3.75

For coding agents, token price is only half the bill. Fewer tool calls and fewer retries matter just as much. That is why a model that is merely “cheap per token” can still be expensive in practice—and why Spark’s task efficiency is the part we will keep testing.

What would make it High Privacy eligible

Any one of these could change the answer quickly:

  1. A Spark endpoint with a published ZDR policy on OpenRouter.
  2. A directly usable zero-retention commitment from Meta.
  3. Open weights under a usable license, followed by a review of the hosting and routing path.

Open weights would create a deployment option; they would not automatically make a service private. Privacy still depends on who runs the inference and what that operator retains.

The verdict

Muse Spark 1.3 is a genuinely interesting coding model. Standard pricing is excellent, its no-training commitment is meaningful, and Contributor is a remarkably explicit data-for-price trade.

Use the Standard route when its retention policy fits the work. Keep sensitive work on a ZDR-qualified route when that is the promise you need. And do not let a 21x discount obscure what the Contributor model ID changes.

Want to compare a model on a real question instead of a benchmark chart? Start a new Chat-O chat, or bring the decision into a Chat Room and get several perspectives at once.

You may also like