PostHog / PostHog/posthog

Slack data warehouse source only offers full-refresh sync — incremental field missing on channel schema?

Open
#59,460 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug team/data-warehouse
Dominant language
Python
Stars
39.9k
Forks
3.4k
Avg merge
6h 51m
Merged PRs (30d)
232

Description

Question for the team

Cross-posting from an internal Slack thread so this doesn't get lost. Wiring this up as a question rather than a bug since the omission may be deliberate — flagging the spot in code that surprised me, but happy to be told "yeah, that's on purpose, here's why."

What I observed

When connecting the Slack data warehouse source (alpha, behind slack-dwh flag) and picking a channel schema, the UI only offers Full refresh as the sync type. Incremental and Append are not selectable.

For a high-volume channel this means we re-pull the entire channel from conversations.history every sync interval, which is expensive (Tier-2 limits) and predictably gets close to the rate-limit storm class of issue that #57567 (draft) is trying to fix.

Where it seems to come from

posthog/temporal/data_imports/sources/slack/settings.py:24-30:

def messages_endpoint_config() -> EndpointConfig:
    return EndpointConfig(
        primary_keys=["channel_id", "ts"],
        partition_keys=["timestamp"],
        partition_mode="datetime",
        partition_format="week",
    )

No incremental_fields=... is passed, so it defaults to [] (EndpointConfig definition at settings.py:9-15).

The UI capabilities for each channel schema are derived directly from that in source.py:200-205:

supports_incremental=len(msg_config.incremental_fields) > 0,  # False
supports_webhooks=webhook_flag_enabled,
supports_append=len(msg_config.incremental_fields) > 0,        # False

So with incremental_fields=[], the schema advertises neither incremental nor append, and the UI hides both options.

What's interesting

The runtime path already handles incremental for channel messages. In slack.py:433-439:

oldest_ts: str | None = None
if should_use_incremental_field and db_incremental_field_last_value is not None:
    # Known limitation: incremental polling only fetches thread replies for parent messages
    # returned by conversations.history in this window. Replies added to older parent threads
    # (parent ts < oldest_ts) are intentionally not captured here and are expected to be
    # addressed by webhook sources.
    oldest_ts = str(db_incremental_field_last_value.timestamp())

That branch reads the last timestamp value and passes it to Slack's oldest parameter on conversations.history. So the engine is already wired up — only the schema declaration is missing the incremental_fields entry that the UI keys off of.

The timestamp column itself looks stable enough to be an incremental field — it's derived from Slack's message ts (microsecond unix timestamp) in _add_timestamp() (slack.py:303-307), and ts is part of the primary key, so it's monotonic per channel for new messages.

Question

Is this:

  1. An oversightincremental_fields should be declared on messages_endpoint_config() and we should expose Incremental / Append in the UI?
  2. Deliberate — there's a known reason (the thread-replies gap noted in the comment, partition format being weekly, something about how ts behaves under workspace clock skew or edits, etc.) that the team wants to address with the webhook source instead of incremental polling?
  3. Pending — incremental on channels is on the roadmap and just hasn't landed?

If (1), I'm happy to PR the change — would look roughly like:

def messages_endpoint_config() -> EndpointConfig:
    return EndpointConfig(
        primary_keys=["channel_id", "ts"],
        partition_keys=["timestamp"],
        partition_mode="datetime",
        partition_format="week",
        incremental_fields=[
            IncrementalField(
                label="timestamp",
                type=IncrementalFieldType.DateTime,
                field="timestamp",
                field_type=IncrementalFieldType.DateTime,
            ),
        ],
    )

Plus a test that asserts channel schemas come back with supports_incremental=True.

If (2) or (3), no PR — just a comment here so the next person who hits this knows the answer.

Context

  • Source: Slack data warehouse source, currently releaseStatus="alpha", gated behind slack-dwh feature flag.
  • Hit while connecting a workspace and selecting a channel to sync — first sync is a 30k+ row backfill, and we're on a 6-hour cadence, so full-refresh every cycle adds up fast.
  • Original source: #48094 (Marcus). Recent activity: #50928 webhook, #57156 channel split, #57966 channel cache, #57567 (draft) rate-limit storm fix.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with posthog/temporal/data_imports/sources/slack/settings.py and the EndpointConfig definition, then trace capability generation in source.py and incremental handling in slack.py. Confirm whether timestamp is an approved incremental field and add or update the relevant schema capability test; done means the intended channel sync options are accurately exposed without breaking thread-reply behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, data-engineering
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.