khone/koʊ.neɪ/
Experimental

Configuration

Gateway config is YAML with PascalCase top-level fields. The config publisher embeds the OpenAPI-ish Spec into the same manifest consumed by the gateway via KHONE_CONFIG_URI.

Top-level fields

FieldTypeDefaultNotes
SpecobjectrequiredOpenAPI-ish route document. Startup fails if it is missing.
AwsRegionstringLambda environment regionOptional Lambda client region override.
MaxInflightInvocationsusize64Must be greater than zero.
MaxInflightRequestsusize4096Must be greater than zero; exceeded requests return 429.
MaxPendingInvocationsusize256Must be greater than zero; exceeded queued batches return 429.
MaxQueueDepthPerKeyusize1000Must be greater than zero; per-key queue cap.
IdleTtlMsu64 (ms)30000Idle batcher eviction time.
DefaultTimeoutMsu64 (ms)2000Per-request fallback timeout (used when an operation does not set x-khone.timeoutMs).
MaxBodyBytesusize (bytes)1048576Maximum accepted request body size. 0 is accepted and rejects every non-empty body.
MaxInvokePayloadBytesusize (bytes)6291456Must be greater than zero; oversized batches are split into multiple invocations when possible. A single request that exceeds this limit fails.
ForwardHeadersobjectforward all decodable headers except hop-by-hopOptional allow/deny policy.

Numeric fields and the boolean profiling may be written as numbers/booleans or as strings.

The gateway reads the manifest at startup from the KHONE_CONFIG_URI environment variable (s3://<bucket>/<key>). The macro wires this environment variable automatically from the generated config publisher; see Bootstrap macro.

Header forwarding

ForwardHeaders:
  Allow:
    - x-tenant-id
    - authorization
  Deny:
    - x-internal-debug

If Allow is non-empty, only those request headers are forwarded to target Lambdas. Deny always wins. Batch-key header dimensions are derived from the original request headers, so filtering a header does not collapse isolation keys.

Route operations

Each operation is declared under Spec.paths:

Spec:
  openapi: 3.0.0
  paths:
    /hello/{id}:
      get:
        operationId: getHello
        x-target-lambda: arn:aws:lambda:us-east-1:123456789012:function:hello
        x-khone:
          maxWaitMs: 25
          maxBatchSize: 8
          invokeMode: buffered

Supported HTTP methods are get, post, put, delete, patch, head, and options. x-target-lambda must be a Lambda function ARN when written as a literal string. Intrinsic function objects such as !GetAtt HelloFunction.Arn are also supported. Paths use {name} placeholders.

x-khone

FieldTypeRequiredDefaultNotes
maxWaitMsu64 (ms)YesNo defaultMaximum time the gateway holds a batch open.
maxBatchSizeusizeYesNo defaultMaximum requests per batch. Must be greater than zero.
keystring[]No[]Extra batch-key dimensions. Supported forms: header:<name> and query:<name>. The literals method, route, lambda, target_lambda, target-lambda are accepted and silently ignored (the gateway always keys by these).
timeoutMsu64 (ms)NoDefaultTimeoutMsPer-operation timeout override.
invokeModeenumNobufferedOne of buffered or response_stream.
profilingboolNofalseEnables Lambda log-tail profiling (extracts the REPORT line for billed duration, init duration, etc.). Adds overhead.
dynamicWaitobjectNoabsentAdaptive wait policy based on observed request rate. Mutually exclusive with durationWait.
durationWaitobjectNoabsentTarget-aware wait policy based on duration probes. Mutually exclusive with dynamicWait.

The gateway always partitions batches by (target_lambda, method, route_template, invokeMode, profiling); any key entries add further partitions on top.

Adaptive wait

dynamicWait is the YAML field for adaptive batching. It derives a per-batch flush window from observed request rate using a sigmoid centered on targetRps. Use it when traffic changes quickly and a fixed maxWaitMs either over-waits at low traffic or under-batches at high traffic.

FieldTypeRequiredDefaultNotes
minWaitMsu64 (ms)YesNo defaultFloor of the computed window. Must be <= maxWaitMs.
targetRpsf64No50.0Request rate where the sigmoid is centered. Must be finite and non-negative.
steepnessf64No0.01Sigmoid steepness around targetRps. Must be finite and greater than zero.
samplingIntervalMsu64 (ms)No100Sampling period for request counts. Must be greater than zero.
smoothingSamplesusizeNo10Moving-average window size. Must be greater than zero.
dynamicWait:
  minWaitMs: 5
  targetRps: 50
  steepness: 0.01
  samplingIntervalMs: 100
  smoothingSamples: 10

Target-aware wait

durationWait is the YAML field for target-aware batching. It uses single-request probe invocations per batch key, smooths the observed durations, and sets the per-batch flush window from fraction of the smoothed target duration. maxWaitMs remains the upper bound. Probes avoid the positive feedback loop that would result from measuring batched durations.

FieldTypeRequiredDefaultNotes
fractionf64YesNo defaultMultiplier applied to the smoothed probe duration. Must be finite and non-negative.
minWaitMsu64 (ms)No0Floor of the computed window. Must be <= maxWaitMs.
probeIntervalMsu64 (ms)No30000How often to schedule a single-request probe flush per batch key. Must be greater than zero.
probeJitterMsu64 (ms)No1000Stable per-batch-key jitter applied to the probe schedule.
smoothingSamplesusizeNo10Moving-average window size over probe samples. Must be greater than zero.
warmupProbesusizeNo1Number of scheduled probe samples required before using duration-derived waits. Must be greater than zero.
durationWait:
  fraction: 0.5
  probeIntervalMs: 30000
  smoothingSamples: 10
  warmupProbes: 1