Skip to main content
Version: 1.5.0

Configuration

This page covers Config and recommended Fory presets.

Config

Fory is configured with:

public struct Config {
public let trackRef: Bool
public let compatible: Bool
public let checkClassVersion: Bool
public let maxDepth: Int
public let maxGraphMemoryBytes: Int64
public let maxTypeFields: Int
public let maxTypeMetaBytes: Int
public let maxSchemaVersionsPerType: Int
public let maxAverageSchemaVersionsPerType: Int
}

Default configuration:

let fory = Fory() // ref=false, compatible=true

Swift supports the xlang wire format only, so there is no xlang option in Config or the Fory initializer.

Threading

Fory is single-threaded and optimized to reuse one read/write context pair on the calling thread. Reuse one instance per thread and do not use the same instance concurrently.

Options

trackRef

Enables shared/circular reference tracking for reference-trackable types.

  • false: No reference table (smaller/faster for acyclic or value-only graphs)
  • true: Preserve object identity for class/reference graphs
let fory = Fory(ref: true)

compatible

Enables compatible schema mode for evolution across versions.

  • false: Faster serialization and smaller size
  • true: Compatible mode (supports add/remove/reorder fields)

Use compatible: false only when every reader and writer always uses the same schema and you want faster serialization and smaller size. For cross-language payloads, set compatible: false only after verifying that every language uses the same schema, or when native types are generated from Fory schema IDL.

let fory = Fory(compatible: false)

checkClassVersion

Controls class-version validation when compatible mode is disabled. When omitted, it defaults to true when compatible: false and false when compatible: true.

let fory = Fory(compatible: false, checkClassVersion: true)

Size and Depth Limits

maxDepth bounds decoded payload nesting depth.

maxGraphMemoryBytes sets an approximate graph-memory gate for one root deserialization. The estimate mainly covers materialized arrays, dictionaries, sets, structs, classes, and objects. It skips leaf values such as strings, binary data, primitive scalars, and dense primitive arrays, so actual process memory can be higher than this value. Leaf values remain protected by byte-availability checks: if the unread input does not contain enough bytes, Fory will not read or create that leaf value. The default limit is a fixed 128 MiB for all root input forms. A positive value overrides the default. Explicit non-positive values are rejected when the runtime is created.

Compatible-mode remote metadata is also limited:

  • maxTypeFields defaults to 512 and limits fields in one received struct metadata body.
  • maxTypeMetaBytes defaults to 4096 and limits encoded body bytes in one received TypeMeta body, excluding the 8-byte header and any extended-size varint.
  • maxSchemaVersionsPerType defaults to 10 and limits accepted remote metadata versions for one logical type.
  • maxAverageSchemaVersionsPerType defaults to 3 and limits the average across accepted remote types. The effective global floor is 8192 schemas.
let fory = Fory(
maxDepth: 5,
maxGraphMemoryBytes: 128 * 1024 * 1024,
maxTypeFields: 512,
maxTypeMetaBytes: 4096,
maxSchemaVersionsPerType: 10,
maxAverageSchemaVersionsPerType: 3
)

Default service payloads

let fory = Fory()

Graph/object identity workloads

let fory = Fory(ref: true)

Same-schema optimization

Use this only when every reader and writer always uses the same schema.

let fory = Fory(compatible: false)

Security

Security-related configuration:

  • Register only the expected generated models before deserializing untrusted payloads.
  • Use checkClassVersion with compatible: false for intentional same-schema payloads.
  • Set maxDepth for the largest nesting depth your service accepts.
  • Set maxGraphMemoryBytes as an approximate gate for collection, map, array, struct, class, and object-heavy payloads. It is not an exact heap cap; leaf values are gated by remaining input bytes.
  • Keep the remote schema metadata limits at their defaults unless the data is not malicious and a trusted peer sends larger metadata or many schema versions.