Skip to content

fix(source-amazon-seller-partner): stream-decode large Brand Analytics reports to prevent OOM - #79669

Open
Anatolii Yatsuk (tolik0) wants to merge 6 commits into
masterfrom
tolik0/source-amazon-seller-partner/streaming-brand-analytics-decoder
Open

Anatolii Yatsuk (tolik0) wants to merge 6 commits into
masterfrom
tolik0/source-amazon-seller-partner/streaming-brand-analytics-decoder

Conversation

@tolik0

@tolik0 Anatolii Yatsuk (tolik0) commented Jun 11, 2026 •

Copy link
Copy Markdown
Contributor

What

Resolves the OOM (exit 137) on large JSON report streams in source-amazon-seller-partner (oncall #12143).

These report streams used a custom GzipJsonDecoder that buffered the entire gzip-decompressed JSON document (multi-GB) plus its parsed object tree in memory — ~10 GB for a 3.45 GB report, OOM-killing even 8–10 GB containers.

How

  • Migrate all 12 large JSON report streams from CustomDecoder(GzipJsonDecoder) to the streaming GzipDecoder{JsonItemsDecoder} (CDK airbytehq/airbyte-python-cdk#1049), which yields array elements one at a time via ijson — bounded memory regardless of report size. Covered streams: the 5 Brand Analytics reports (Search Terms, Market Basket, Repeat Purchase, Alternate Purchase, Item Comparison), the 3 Sales and Traffic reports (by ASIN, by date, by month), and the 4 Vendor reports (Sales, Inventory, Forecasting FRESH/RETAIL).
  • Amazon serves these documents gzip-compressed but labels them Content-Encoding: identity by default, so the header-based GzipDecoder would skip decompression. Request enableContentEncodingUrlHeader=true on getReportDocument (scoped to these streams) so Amazon sets an honest Content-Encoding (gzip when compressed, identity when not). CSV/XML report downloads are untouched.
  • Bump the SDM baseImage to CDK 7.23.1, which includes both JsonItemsDecoder and the ijson use_float=True fix (#1052) so non-integer fields (e.g. Search Terms clickShare/conversionShare) serialize as floats instead of failing as Decimal.
  • Remove the now-unused custom GzipJsonDecoder (no longer referenced by any stream). CSV/XML decoders remain.

Validation (real account at cloud memory limits)

GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT, 3.45 GB uncompressed / 8,533,151 records:

Build 2 GiB 4 GiB 10 GiB
Released 5.7.7 (old GzipJsonDecoder) OOM 137 OOM 137 OOM 137
This PR (JsonItemsDecoder, CDK 7.23.1) ✅ exit 0, 8,533,151 records, ~150 MB peak — —

Same report, same 2 GiB cap: the old decoder OOM-kills even at 10 GiB, while this build streams all 8.5M records under 2 GiB with no Decimal serialization errors. Validated with the official preview image built from this branch.

Both the compressed (Content-Encoding: gzip) and uncompressed (identity) download paths are covered by test_given_compressed_report_when_read_then_return_records and test_given_report_when_read_then_return_records respectively.

Note for reviewers

Two of the Brand Analytics streams — GET_BRAND_ANALYTICS_ALTERNATE_PURCHASE_REPORT and GET_BRAND_ANALYTICS_ITEM_COMPARISON_REPORT — now return FATAL "This report is now deprecated." from Amazon. They're migrated for consistency but are effectively dead upstream; removing them can be handled separately.

Note: the OOM and Amazon-side report FATAL (generation failures) are distinct failure modes. This PR removes the OOM whenever Amazon returns a DONE report; it does not affect cases where Amazon fails to generate the report at all.

🤖 Generated with Claude Code

@octavia-bot
octavia-bot Bot marked this pull request as draft June 11, 2026 13:16
@octavia-bot

octavia-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Note

📝 PR Converted to Draft

More info...

Thank you for creating this PR. As a policy to protect our engineers' time, Airbyte requires all PRs to be created first in draft status. Your PR has been automatically converted to draft status in respect for this policy.

As soon as your PR is ready for formal review, you can proceed to convert the PR to "ready for review" status by clicking the "Ready for review" button at the bottom of the PR page.

To skip draft status in future PRs, please include [ready] in your PR title or add the skip-draft-status label when creating your PR.

…s reports to prevent OOM

The Brand Analytics report streams buffered the entire gzip-decompressed JSON document
(multi-GB) into memory, causing OOM kills (exit 137) on large sellers. Switch their
download_decoder to the streaming GzipDecoder{JsonItemsDecoder}, which yields records
one at a time via ijson.

Amazon serves these report documents gzip-compressed but labels them
'Content-Encoding: identity' by default, so the header-based GzipDecoder would skip
decompression. Request enableContentEncodingUrlHeader=true on getReportDocument so Amazon
sets an honest Content-Encoding (gzip when compressed, identity when not).

Validated end-to-end on real reports: 3.2GB search-terms report peak memory ~10GB -> ~150MB
with identical records; repeat-purchase stream reads 475 records cleanly.

Uses prerelease CDK 7.21.2.post1.dev27346905256 (JsonItemsDecoder, airbytehq/airbyte-python-cdk#1049);
baseImage to be finalized to the official SDM release once #1049 merges.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

👋 Greetings, Airbyte Team Member!

Here are some helpful tips and reminders for your convenience.

💡 Show Tips and Tricks

PR Slash Commands

Airbyte Maintainers (that's you!) can execute the following slash commands on your PR:

  • 🛠️ Quick Fixes
    • /format-fix - Fixes most formatting issues.
    • /bump-version - Bumps connector versions, scraping changelog description from the PR title.
      • Bump types: patch (default), minor, major, major_rc, rc, promote.
      • The rc type is a smart default: applies minor_rc if stable, or bumps the RC number if already RC.
      • The promote type strips the RC suffix to finalize a release.
      • Example: /bump-version type=rc or /bump-version type=minor
    • /bump-progressive-rollout-version - Alias for /bump-version type=rc. Bumps with an RC suffix and enables progressive rollout.
  • ❇️ AI Testing and Review (internal link: AI-SDLC Docs):
    • /ai-prove-fix - Runs prerelease readiness checks, including testing against customer connections.
    • /ai-canary-prerelease - Rolls out prerelease to 5-10 connections for canary testing.
    • /ai-review - AI-powered PR review for connector safety and quality gates.
  • 📝 AI Documentation:
    • /ai-docs-review - AI-powered documentation review for PRs with connector changes.
    • /ai-create-docs-pr - Creates a documentation PR for connector changes, stacked on the current PR.
  • 🚀 Connector Releases:
    • /publish-connectors-prerelease - Publishes pre-release connector builds (tagged as {version}-preview.{git-sha}) for all modified connectors in the PR.
  • ☕️ JVM connectors:
    • /update-connector-cdk-version connector=<CONNECTOR_NAME> - Updates the specified connector to the latest CDK version.
      Example: /update-connector-cdk-version connector=destination-bigquery
  • 🐍 Python connectors:
    • /poe connector source-example lock - Run the Poe lock task on the source-example connector, committing the results back to the branch.
    • /poe source example lock - Alias for /poe connector source-example lock.
    • /poe source example use-cdk-branch my/branch - Pin the source-example CDK reference to the branch name specified.
    • /poe source example use-cdk-latest - Update the source-example CDK dependency to the latest available version.
  • ⚙️ Admin commands:
    • /force-merge reason="<REASON>" - Force merges the PR using admin privileges, bypassing CI checks. Requires a reason.
      Example: /force-merge reason="CI is flaky, tests pass locally"
📚 Show Repo Guidance

Helpful Resources

📝 Edit this welcome message.

@github-actions

github-actions Bot commented Jun 11, 2026 •

Copy link
Copy Markdown
Contributor

source-amazon-seller-partner Connector Test Results

554 tests   552 ✅  1h 59m 29s ⏱️
  1 suites    0 💤
  1 files      2 ❌

For more details on these failures, see this check.

Results for commit 7e4cb2c.

♻️ This comment has been updated with latest results.

…Decoder; mock honest Content-Encoding

Bump the unit-test airbyte-cdk to the prerelease that provides JsonItemsDecoder
(7.21.2.post1.dev27346905256) so the manifest validates, and set Content-Encoding: gzip
on the compressed report-download mock to mirror enableContentEncodingUrlHeader so the
header-based GzipDecoder decompresses it. 317 report-based stream tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tolik0
Anatolii Yatsuk (tolik0) marked this pull request as ready for review June 11, 2026 14:19
@tolik0

Anatolii Yatsuk (tolik0) commented Jun 11, 2026 •

Copy link
Copy Markdown
Contributor Author

/publish-connectors-prerelease

Pre-release Connector Publish Started

Publishing pre-release build for connector source-amazon-seller-partner.
PR: #79669

Pre-release versions will be tagged as {version}-preview.ad7a98a
and are available for version pinning via the scoped_configuration API.

View workflow run
Pre-release Publish: SUCCESS ✅

Docker image (pre-release):
airbyte/source-amazon-seller-partner:5.7.8-preview.ad7a98a

Docker Hub: https://hub.docker.com/layers/airbyte/source-amazon-seller-partner/5.7.8-preview.ad7a98a

Registry JSON:

…arge JSON report streams

Migrate all 12 large JSON report streams (Brand Analytics, Sales and Traffic,
Vendor) to the streaming JsonItemsDecoder on CDK 7.23.1. 7.23.1 includes the
ijson use_float fix, so float fields (e.g. Search Terms clickShare/conversionShare)
serialize correctly instead of failing as Decimal.

Validated against a real 3.45 GB Search Terms report: the released 5.7.7
OOM-kills at a 2, 4, and even 10 GiB cap, while this build streams all
8,533,151 records under a 2 GiB cap (peak ~150 MiB), exit 0, no Decimal errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tolik0

Anatolii Yatsuk (tolik0) commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor Author

/publish-connectors-prerelease

Pre-release Connector Publish Started

Publishing pre-release build for connector source-amazon-seller-partner.
PR: #79669

Pre-release versions will be tagged as {version}-preview.7e4cb2c
and are available for version pinning via the scoped_configuration API.

View workflow run
Pre-release Publish: SUCCESS ✅

Docker image (pre-release):
airbyte/source-amazon-seller-partner:5.7.8-preview.7e4cb2c

Docker Hub: https://hub.docker.com/layers/airbyte/source-amazon-seller-partner/5.7.8-preview.7e4cb2c

Registry JSON:

@github-actions

Copy link
Copy Markdown
Contributor

Deploy preview for airbyte-docs ready!

Project:airbyte-docs
Status: ✅  Deploy successful!
Preview URL:https://airbyte-docs-cpfs2kk2i-airbyte-growth.vercel.app
Latest Commit:7e4cb2c

Deployed with vercel-action

Anatolii Yatsuk (tolik0) and others added 3 commits June 16, 2026 15:59
…in vendor forecasting compressed-report mock

The vendor forecasting (FRESH/RETAIL) compressed-report test builds its mocked
response manually and was dropping the response headers, so the served gzip body
had no Content-Encoding: gzip. After migrating these streams to the header-based
GzipDecoder + JsonItemsDecoder, the decoder no longer decompressed the body and
ijson received raw gzip bytes (IncompleteJSONError). Pass the headers through so
the mock mirrors Amazon's enableContentEncodingUrlHeader=true behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
All 12 JSON report streams now use the native streaming JsonItemsDecoder, so the
custom GzipJsonDecoder is no longer referenced in the manifest. Remove the dead class.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n-seller-partner/streaming-brand-analytics-decoder

# Conflicts:
#	docs/integrations/sources/amazon-seller-partner.md

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants