Skip to content

Add msgpack_pack_buf_size opt to tune initial Packer allocation - #70117

Open
dwoz wants to merge 3 commits into
saltstack:masterfrom
dwoz:dwoz/feat/msgpack-pack-buf-size-tunable
Open

Add msgpack_pack_buf_size opt to tune initial Packer allocation#70117
dwoz wants to merge 3 commits into
saltstack:masterfrom
dwoz:dwoz/feat/msgpack-pack-buf-size-tunable

Conversation

@dwoz

@dwoz dwoz commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

What

Adds a single new master/minion/api config option, msgpack_pack_buf_size (bytes), that controls the initial buf_size passed to the C msgpack.Packer used by Salt's transport framing (salt.transport.frame), payload packaging (salt.payload), and msgpack serializer (salt.serializers.msgpack).

The value is cached at daemon startup in salt.utils.msgpack via a small set_pack_buf_size helper called from apply_master_config, apply_minion_config, and api_config, so downstream helpers that do not have __opts__ in scope can honor the opt without threading it through every call site.

Why

Exposes the knob so operators can pre-size the Packer buffer for workloads with predictable payload sizes and reduce realloc churn. Effect is workload-dependent -- this PR is not claiming a memory or throughput improvement; it just makes the underlying msgpack tunable reachable from Salt config.

Default / compat

Default is 0, which preserves msgpack's own default and current behavior byte-for-byte. Additive only; no wire format change.

Test plan

  • New unit tests in tests/pytests/unit/utils/test_msgpack.py covering default (no override), positive value forwarded as buf_size, explicit caller kwarg still wins, bad values (non-int / negative) ignored without crashing, and packed-output byte-identical regardless of buf_size.
  • Existing tests/pytests/unit/config/, tests/pytests/unit/test_payload.py, tests/pytests/unit/serializers/test_serializers.py still pass.

Expose a single new master/minion/api config option,
``msgpack_pack_buf_size``, that controls the initial ``buf_size`` passed to
the underlying C ``msgpack.Packer`` used by Salt's transport framing,
payload packaging, and msgpack serializer helpers.

The value is cached at daemon startup in ``salt.utils.msgpack`` via a small
``set_pack_buf_size`` helper called from ``apply_master_config``,
``apply_minion_config``, and ``api_config`` so downstream helpers that do
not have ``__opts__`` in scope can honor the opt without changes to their
call sites.

Default is ``0``, which preserves msgpack's own default (auto-grow-from-
256KB) and current behavior byte-for-byte.  A positive value pre-allocates
that many bytes on ``Packer`` construction, which can reduce realloc churn
for workloads with predictable payload sizes.  This is a tuning knob only;
it does not change the wire format or any observable behavior at the
default value.
@dwoz
dwoz requested a review from a team as a code owner August 22, 2026 22:12
Flip the ``msgpack_pack_buf_size`` default from ``0`` (msgpack's own
256 KiB progressive growth) to ``1048576`` (1 MiB).  The new default
pre-allocates a workload-appropriate ``Packer`` buffer that fits typical
Salt payloads -- state returns, grains, event payloads -- in a single
allocation, eliminating the realloc chain on the common path.  The opt
still honors ``0`` as an explicit escape hatch to restore the original
msgpack behavior byte-for-byte; the wire format is unchanged.

Also widen the opt to accept a human-friendly size string in the master
and minion config, matching Salt's convention for other byte-count
knobs.  ``msgpack_pack_buf_size: 1MB`` (or ``512KiB``, ``2G``, etc.) is
parsed via ``salt.utils.stringutils.human_to_bytes`` and normalized to
an integer inside ``set_pack_buf_size``, so downstream helpers still see
a plain int.  Bad or unparseable strings are ignored with a debug log
and leave the previous cached value in place, so bad opts never crash a
daemon.
@dwoz

dwoz commented Aug 22, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up pushed in 4a29cd5:

  • Default flipped from 0 to 1048576 (1 MiB) -- pre-allocates a workload-appropriate Packer buffer that fits typical Salt payloads (state returns, grains, event payloads) in a single allocation, eliminating the realloc chain on the common path. Wire format unchanged.
  • Opt-out preserved: msgpack_pack_buf_size: 0 (int or string) restores the msgpack default (256 KiB progressive growth).
  • Also widened the opt to accept human-friendly size strings -- msgpack_pack_buf_size: 1MB (or 512KiB, 2G, etc.) -- parsed via salt.utils.stringutils.human_to_bytes and normalized to int inside set_pack_buf_size. Bad/unparseable strings are ignored with a debug log and leave the previous cached value in place.
  • Tests + docs updated; pre-commit clean; all 68 msgpack unit tests pass locally.

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

Labels

test:full Run the full test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant