# Replace Google Cloud Pub/Sub with KubeMQ (/deploy/scenarios/replace/replace-gcp-pubsub)



<Callout type="info">
  You need a license key to start KubeMQ — it's free, about 2-3 minutes (it includes creating a free account). 

  [Get one](/deploy/license-key)

  . Step 1 below starts the broker with the connector enabled.
</Callout>

Point your existing Google Cloud Pub/Sub client at KubeMQ by setting one environment
variable — the connection changes, your topics, subscriptions, and application code
don't.

**Drop-in level:** endpoint-only ([legend](/deploy/scenarios/replace#drop-in-levels))

## 1 · Enable the connector [#1--enable-the-connector]

The GCP Pub/Sub connector is disabled by default. Start KubeMQ with it turned on:

<RunKubeMQ env="{ CONNECTORS_GCP_ENABLE: 'true' }" ports="[8085, 50000]" />

## 2 · Point your client at KubeMQ [#2--point-your-client-at-kubemq]

Set `PUBSUB_EMULATOR_HOST` to the connector's gRPC port. The SDK clears its Google
credentials and dials insecure gRPC automatically — no code change.

Before (real Google Cloud):

```bash
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json
export GOOGLE_CLOUD_PROJECT=my-project
```

After (KubeMQ):

```bash
export PUBSUB_EMULATOR_HOST=localhost:8085
export PUBSUB_PROJECT_ID=my-project   # arbitrary; the connector ignores the project segment
unset GOOGLE_APPLICATION_CREDENTIALS
```

## 3 · Smoke test [#3--smoke-test]

Run a publish → pull → acknowledge round-trip against the emulator endpoint:

```python
import os, time
from google.cloud import pubsub_v1

os.environ["PUBSUB_EMULATOR_HOST"] = "localhost:8085"
os.environ["PUBSUB_PROJECT_ID"] = "smoke-test"

pub = pubsub_v1.PublisherClient()
sub = pubsub_v1.SubscriberClient()

t = pub.topic_path("smoke-test", "smoke-topic")        # -> gcp.smoke-topic
s = sub.subscription_path("smoke-test", "smoke-sub")   # -> gcp.sub.smoke-sub

pub.create_topic(request={"name": t})
sub.create_subscription(request={"name": s, "topic": t})

future = pub.publish(t, data=b"smoke-payload")
print(f"published id={future.result()}")

time.sleep(0.5)
resp = sub.pull(request={"subscription": s, "max_messages": 1})
assert len(resp.received_messages) == 1
sub.acknowledge(request={"subscription": s, "ack_ids": [resp.received_messages[0].ack_id]})
print("smoke test PASSED — message received and acked")
```

Expected output:

```text
published id=1
smoke test PASSED — message received and acked
```

(adapted from the [full verification smoke
test](/connectors/gcp-pub-sub/reference/migration-from-gcp#verification-smoke-test))

## What carries over — and what doesn't [#what-carries-over--and-what-doesnt]

Your Pub/Sub client code, topic/subscription calls, and message attributes carry over
unchanged. GCP auth, IAM, and TLS don't — the connector runs in emulator mode with no
authentication — and message ordering is node-local, not cluster-wide.

<Cards>
  <Card title="GCP Pub/Sub getting started" href="/connectors/gcp-pub-sub/tutorials/getting-started" description="The full multi-language walkthrough." />

  <Card title="Migrating from GCP Pub/Sub" href="/connectors/gcp-pub-sub/reference/migration-from-gcp" description="The complete compatibility matrix and deviations." />
</Cards>

## Didn't work? [#didnt-work]

<Callout type="warn">
  * **Wrong port** — the connector listens on `8085`, not Google's default. Confirm
    `PUBSUB_EMULATOR_HOST` points at `localhost:8085`.
  * **Connector not enabled** — a stock server doesn't bind port `8085` until
    `CONNECTORS_GCP_ENABLE=true` is set. Check `docker logs kubemq` for a bind error.
  * **Client still tries real GCP auth** — if `PUBSUB_EMULATOR_HOST` isn't set (or
    credentials weren't cleared), the SDK authenticates against Google instead of the
    connector.
</Callout>
