Skip to content

Accounting for component conversion work in an execution fuel budget #14430

Open

Description

@wilfreddenton

I run Wasmtime components in an embedding where guest instructions and host work share an execution fuel budget. Guest-to-host lifting consumes hostcall_fuel, but that allowance starts over for each lift and does not reduce Store::get_fuel(). I need repeated conversions to count against the execution budget, including work done before a conversion fails.

I can see two possible approaches:

  1. Wasmtime could optionally charge Store fuel as lifting consumes its existing allowance, at a configurable price.
  2. Wasmtime could expose allowance consumption, including partial consumption on errors, and provide reliable points for the embedding to set a limit from remaining fuel before each lift and settle the cost before execution continues. A hook might help, but I am not sure the current hooks cover all those points.

Would you recommend either approach, or a different API for this?

Activity

  1. alexcrichton commented on Sep 29, 2026

    @alexcrichton
    Member

    It seems reasonable to me to go ahead and discount the fuel from the store fuel, if enabled, as well on successful lifts/lowers if it doesn't add too much overhead. Perhaps a Drop for the LiftContext might be the best place to put that, but I'm not entirely sure. I agree that adding hooks is probably going to be a bit messy, so just automatically doing this is probably the way to go

  2. wilfreddenton commented on Sep 29, 2026

    @wilfreddenton
    Author

    Thanks, Alex. Settling in LiftContext::Drop would account for work after completion, but we need to enforce the shared fuel budget before the work occurs. Would you be open to opt-in Store fuel deduction at the existing LiftContext::consume_fuel checks?

    I'd also like equivalent accounting for lowering, covering host-side conversion and copying. Would you prefer to include lowering initially or address it separately?

  3. alexcrichton commented on Sep 29, 2026

    @alexcrichton
    Member

    If it's not too bad to add this to consume_fuel that seems ok yeah. For lowering I'm hesitant to have fuel worm its way so so deeply into everywhere in Wasmtime so I'm tempted to leave that up to embedders to do since the hook isn't already there. Is it difficult though on the embedder side to account for the work the host is doing in fuel?

  4. wilfreddenton commented on Sep 30, 2026

    @wilfreddenton
    Author

    Lowering accounting turned out to be manageable on the embedder side. My strategy was to charge at two points:

    Host-function results returned to the guest. wasmtime lowers these after the registered callback returns. I wrapped linker registration so each callback runs the host function, calculates a lowering charge from its result, deducts Store fuel, and then returns the result. If charging fails, lowering never starts. I used bindgen’s wasmtime_crate option to route generated registrations through the same wrapper.

    Arguments passed into guest exports. I accumulated their lowering cost during the existing argument-construction traversal, then deducted it before calling Wasmtime.

    Leaving lowering to embedders looks workable. Do you see any improvements to this embedder-side approach? Deducting Store fuel directly in lifting’s existing consume_fuel checks should address the remaining gap.

  5. alexcrichton commented on Sep 30, 2026

    @alexcrichton
    Member

    That sounds reasonable enough to me yeah

  6. carsonfarmer commented on Oct 2, 2026

    @carsonfarmer

    A data point from an embedder: in wasmtime-wasi-http 49, fields.from-list lifts the whole list<tuple<string, list<u8>>> before its 128 KiB field-size check runs, so a call that will be refused can still allocate up to the hostcall-fuel budget first. I use epoch deadlines rather than Store fuel, so for me the per-call budget is the only bound, and I've lowered it to 32 MiB with set_hostcall_fuel. It might be worth a line in the wasmtime-wasi-http docs suggesting embedders do the same.

  7. RajaBabu15 commented on Oct 31, 2026

    @RajaBabu15

    I've opened #15104 for this, following the approach agreed above: an opt-in per-store setting (Store::set_hostcall_fuel_consumes_store_fuel) that makes LiftContext::consume_fuel also deduct Store fuel before the lift continues, trapping with OutOfFuel when it runs out. Lowering is left to embedders as discussed.

    @alexcrichton I listed a few open questions in the PR (naming, Store vs Config, and whether the setter should error without Config::consume_fuel). Happy to adjust.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    wasmtime:fuelWasmtime issues related to fuel consumption

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions