Skip to content

supabase realtime listener stops receiving events after sometime #1134

@ekorman

Description

@ekorman

Bug report

  • [ x ] I confirm this is a bug with Supabase, not with my own application.
  • [ x ] I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

My supabase realtime listener stops receiving events after a while, without giving an errors.

To Reproduce

Here is the code snippet I'm using

async def realtime_insert_table_listener(table: str, cb: callable):
    while True:
        try:
            await async_supabase.realtime.connect()

            while not async_supabase.realtime.is_connected:
                await asyncio.sleep(0.2)

            channel = async_supabase.channel(table)
            channel.on_postgres_changes(
                event="INSERT",
                schema="public",
                table=table,
                callback=cb,
            )
            

            await channel.subscribe(
                lambda status, err: status
                == RealtimeSubscribeStates.SUBSCRIBED
                and logger.info("Successfully subscribed")
            )
            while True:
                await asyncio.sleep(10)
        except ConnectionClosedError as exc:
            logger.warning(
                "Connection closed unexpectedly: %s. Will retry...", exc
            )
        except Exception as exc:
            logger.exception(
                "Error in realtime listener: %s. Will retry...", exc
            )
        finally:
            try:
                if async_supabase.realtime.is_connected:
                    logger.info("Closing realtime connection...")
                    await async_supabase.realtime.close()
            except Exception:
                logger.exception("Error while closing realtime connection")

        # Backoff or small delay before attempting to reconnect
        logger.info("Will attempt to reconnect in 5 seconds...")
        await asyncio.sleep(5)

System information

  • OS: ubuntu

package information:

>>> supabase.__version__
'2.15.2'
>>> realtime.__version__
'2.4.3'
>>> websockets.__version__
'14.2'

Activity

Marzhal

Marzhal commented on Jun 22, 2025

@Marzhal

Please assign me this issue :)

Rasheek16

Rasheek16 commented on Jun 23, 2025

@Rasheek16

Can i take up this issue?

silentworks

silentworks commented on Jun 24, 2025

@silentworks
Contributor

@ekorman how long before it stops receiving events? what environment are you running the code above in and how are you running it?

ekorman

ekorman commented on Jun 24, 2025

@ekorman
Author

@ekorman how long before it stops receiving events? what environment are you running the code above in and how are you running it?

@silentworks i run it like this

asyncio.run(realtime_insert_table_listener(table=table, cb=cb))

inside a docker container (based on python:3.11-slim ) on an ubuntu VM.

hard to say exactly how long before it stops receiving events but seems like it works for between 12-36 hours before no longer receiving messages (or erroring) and never recovering.

skusez

skusez commented on Jul 16, 2025

@skusez

Experiencing the same, 3.12-slim, supabase 2.16.0 - ubuntu amd64 vps inside docker

I setup a heartbeat that sends a message to the giveaway-events channel using realtime.send from database, it runs every 1 minute. I simply log the message in python

It emits logs exactly 60 times before silently stopping (60 mins)

...
 self.supabase_client = await create_async_client(REALTIME_URL, API_KEY)
        channel = self.supabase_client.channel("giveaway-events")
        channel.on_broadcast("heartbeat", self.handle_heartbeat)
        await channel.subscribe()
...
def handle_heartbeat(self, payload):
        """Handle when a heartbeat is received"""
        asyncio.create_task(self._handle_heartbeat(payload))

    async def _handle_heartbeat(self, payload):
        """Handle when a heartbeat is received"""
        await self.logger.info(f"Received heartbeat: {payload}")
...

Ran the same test in supabase studios realtime inspector and logs keep coming through with no hiccups (self hosted, running within the same VPS

Image

)

skusez

skusez commented on Jul 16, 2025

@skusez

Experiencing the same, 3.12-slim, supabase 2.16.0 - ubuntu amd64 vps inside docker

I setup a heartbeat that sends a message to the giveaway-events channel using realtime.send from database, it runs every 1 minute. I simply log the message in python

It emits logs exactly 60 times before silently stopping (60 mins)

...
self.supabase_client = await create_async_client(REALTIME_URL, API_KEY)
channel = self.supabase_client.channel("giveaway-events")
channel.on_broadcast("heartbeat", self.handle_heartbeat)
await channel.subscribe()
...
def handle_heartbeat(self, payload):
"""Handle when a heartbeat is received"""
asyncio.create_task(self._handle_heartbeat(payload))

async def _handle_heartbeat(self, payload):
    """Handle when a heartbeat is received"""
    await self.logger.info(f"Received heartbeat: {payload}")

...

Ran the same test in supabase studios realtime inspector and logs keep coming through with no hiccups (self hosted, running within the same VPS
Image

)

The fact it drops out after exactly 1 hour leads me to believe its linked with the refresh token issue that has a PR open here #1171

silentworks

silentworks commented on Jul 16, 2025

@silentworks
Contributor

@skusez provide a full reproducible example please. This should include the Dockerfile setup along with the Python code. Also have you tested it with the PR you stated above to see if it fixes the issue?

silentworks

silentworks commented on Jul 16, 2025

@silentworks
Contributor

I've setup a test locally that has been running for more than an hour and it's still receiving messages. This test was without the docker container, I'm going to try this now with the docker container to see if it makes a difference.

skusez

skusez commented on Jul 16, 2025

@skusez

I tested with the PR and still was silently failing around the hour mark, I did have to patch the package as there was a top level await causing a runtime error

My Dockerfile:


FROM python:3.12-slim

WORKDIR /app

RUN apt-get update && apt-get install -y --no-install-recommends \
    git \
    gcc \
    libpq-dev \
    ca-certificates \
    build-essential \
    && rm -rf /var/lib/apt/lists/*


COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
    # Remove top-level await bug in supabase async client
    RUN sed -i "s/await self.realtime.set_auth(access_token)/self.realtime.set_auth(access_token)/" /usr/local/lib/python3.12/site-packages/supabase/_async/client.py

COPY . .

WORKDIR /app
CMD ["python", "main.py"]

silentworks

silentworks commented on Jul 16, 2025

@silentworks
Contributor

@skusez if you had to remove the top level await then there is something wrong about the package version you are using, we have no top level await in the library code.

silentworks

silentworks commented on Jul 16, 2025

@silentworks
Contributor

I've tested this inside of a docker container and still not getting the issue you are having. You can check the code in the repo here https://github.com/silentworks/sb-python-issues/tree/main/supabase_py_1134

Kabya002

Kabya002 commented on Jul 16, 2025

@Kabya002

Hi @skusez — appreciate you testing the PR!

Just to clarify: the main goal of PR #1171 was to fix an Authorization header desync after token refreshes — specifically affecting service clients like auth.admin.list_users() returning 403s due to stale tokens.

The issue you're seeing sounds different:

  • Realtime connections silently dropping after ~60 minutes
  • No reconnect or error raised
  • Possibly related to WebSocket expiry, heartbeat loss, or container idle behavior

That said, you're absolutely right to consider whether the realtime client is staying updated after token refreshes — it’s something we now handle via set_auth(...) in the patch.

Re: the await self.realtime.set_auth(...) change — that line is inside an async method, so if you're seeing a top-level await error, you might be testing an older commit. The current version should not raise that.

If you end up isolating the 60-minute drop to auth-related behavior, I’d be happy to collaborate on a repro or patch!

silentworks

silentworks commented on Jul 16, 2025

@silentworks
Contributor

@Kabya002 you should state the above on the PR that you opened as there should never be a scenario where auth.admin.list_users() has a stale token as it should only ever be called with the service_role key. Add the comments above on the PR so we can discuss this further.

Kabya002

Kabya002 commented on Jul 17, 2025

@Kabya002

@silentworks I've posted the clarification regarding auth.admin.list_users() and service_role usage in PR #1171 as you suggested.

skusez

skusez commented on Jul 23, 2025

@skusez

Hey just an update, my errors were actually an internal issue with my VPSs

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @silentworks@ekorman@Kabya002@skusez@Marzhal

        Issue actions

          supabase realtime listener stops receiving events after sometime · Issue #1134 · supabase/supabase-py