Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

CHANGED

- Changed the default large-payload externalization threshold (`LargePayloadStorageOptions.threshold_bytes`) from 900,000 bytes to 262,144 bytes (256 KiB), matching the .NET SDK default. Behavioral change (not source/binary breaking): payloads larger than 256 KiB are now externalized by default.

## v1.7.0

ADDED
Expand Down
6 changes: 3 additions & 3 deletions docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ pip install durabletask[azure-blob-payloads]
#### How it works

1. When the worker or client sends a payload that exceeds the
configured threshold (default 900 KB), the payload is
configured threshold (default 256 KiB), the payload is
compressed (GZip, enabled by default) and uploaded to the
external store.
2. The original payload in the gRPC message is replaced with a
Expand All @@ -307,7 +307,7 @@ from durabletask.extensions.azure_blob_payloads import BlobPayloadStore, BlobPay
store = BlobPayloadStore(BlobPayloadStoreOptions(
connection_string="DefaultEndpointsProtocol=https;...",
container_name="durabletask-payloads", # default
threshold_bytes=900_000, # default (900 KB)
threshold_bytes=262_144, # default (256 KiB)
max_stored_payload_bytes=10_485_760, # default (10 MB)
enable_compression=True, # default
))
Expand Down Expand Up @@ -351,7 +351,7 @@ store = BlobPayloadStore(BlobPayloadStoreOptions(

| Option | Default | Description |
|---|---|---|
| `threshold_bytes` | 900,000 (900 KB) | Payloads larger than this are externalized |
| `threshold_bytes` | 262,144 (256 KiB) | Payloads larger than this are externalized |
| `max_stored_payload_bytes` | 10,485,760 (10 MB) | Maximum size for externalized payloads |
| `enable_compression` | `True` | GZip-compress payloads before uploading |
| `container_name` | `"durabletask-payloads"` | Azure Blob container name |
Expand Down
2 changes: 1 addition & 1 deletion docs/supported-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ with DurableTaskSchedulerWorker(
state = c.wait_for_orchestration_completion(instance_id, timeout=60)
```

In this example, any payload exceeding the threshold (default 900 KB) is compressed and uploaded to
In this example, any payload exceeding the threshold (default 256 KiB) is compressed and uploaded to
the configured Azure Blob container. When the worker or client reads the message, it downloads and
decompresses the payload automatically.

Expand Down
6 changes: 3 additions & 3 deletions durabletask/payload/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ class LargePayloadStorageOptions:

Attributes:
threshold_bytes: Payloads larger than this value (in bytes) will
be externalized to the payload store. Defaults to 900,000
(900 KB), matching the .NET SDK default.
be externalized to the payload store. Defaults to 262,144
(256 KiB), matching the .NET SDK default.
max_stored_payload_bytes: Maximum payload size (in bytes) that
can be stored externally. Payloads exceeding this limit
will cause an error. Defaults to 10,485,760 (10 MB).
enable_compression: When ``True`` (the default), payloads are
GZip-compressed before uploading.
"""
threshold_bytes: int = 900_000
threshold_bytes: int = 262_144
max_stored_payload_bytes: int = 10 * 1024 * 1024 # 10 MB
enable_compression: bool = True

Expand Down
6 changes: 3 additions & 3 deletions examples/large_payload/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ python app.py
The example schedules two orchestrations:

- **Small payload** — The input and output stay inline in the gRPC
messages (below the 1 KB threshold configured in the example).
- **Large payload** — The activity output (~70 KB) exceeds the
messages (below the 256 KiB threshold configured in the example).
- **Large payload** — The activity output (~342 KiB) exceeds the
threshold and is automatically externalized to blob storage and
retrieved transparently.

Expand All @@ -106,7 +106,7 @@ The `BlobPayloadStoreOptions` class supports the following settings:

| Option | Default | Description |
|---|---|---|
| `threshold_bytes` | 900,000 (900 KB) | Payloads larger than this are externalized |
| `threshold_bytes` | 262,144 (256 KiB) | Payloads larger than this are externalized |
| `max_stored_payload_bytes` | 10,485,760 (10 MB) | Maximum externalized payload size |
| `enable_compression` | `True` | GZip-compress before uploading |
| `container_name` | `"durabletask-payloads"` | Blob container name |
Expand Down
6 changes: 3 additions & 3 deletions examples/large_payload/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ def main():
# Configure the blob payload store
store = BlobPayloadStore(BlobPayloadStoreOptions(
connection_string=storage_conn_str,
# Use a low threshold so that we can see externalization in action
threshold_bytes=1_024,
# 256 KiB, matching the SDK default; larger payloads are externalized
threshold_bytes=262_144,
))

secure_channel = endpoint.startswith("https://")
Expand Down Expand Up @@ -120,7 +120,7 @@ def main():
# (the report will be externalized to blob storage automatically)
print("\n--- Large payload (externalized to blob storage) ---")
instance_id = c.schedule_new_orchestration(
large_payload_orchestrator, input=10_000)
large_payload_orchestrator, input=50_000)
state = c.wait_for_orchestration_completion(instance_id, timeout=60)
if state and state.runtime_status == client.OrchestrationStatus.COMPLETED:
print(f"Result: {state.serialized_output}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
TEST_CONTAINER = f"dts-payloads-{uuid.uuid4().hex[:8]}"

# A low threshold so we can trigger externalization without massive strings.
# In production the default is 900 KB; here we use 1 KB for fast tests.
# In production the default is 256 KiB; here we use 1 KB for fast tests.
THRESHOLD_BYTES = 1_024

# Pin API version to one that Azurite supports.
Expand Down
2 changes: 1 addition & 1 deletion tests/durabletask/test_large_payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ def test_default_options(self):
connection_string="UseDevelopmentStorage=true",
))
opts = store.options
assert opts.threshold_bytes == 900_000
assert opts.threshold_bytes == 262_144
assert opts.max_stored_payload_bytes == 10 * 1024 * 1024
assert opts.enable_compression is True
assert opts.container_name == "durabletask-payloads"
Expand Down
2 changes: 1 addition & 1 deletion tests/durabletask/test_large_payload_e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
TEST_CONTAINER = f"e2e-payloads-{uuid.uuid4().hex[:8]}"

# A low threshold so we can trigger externalization without massive strings.
# In production the default is 900 KB; here we use 1 KB for fast tests.
# In production the default is 256 KiB; here we use 1 KB for fast tests.
THRESHOLD_BYTES = 1_024

# Pin API version to one that Azurite supports.
Expand Down
Loading