
Some analytics data is not allowed to leave the building. Banks, insurers, public bodies and defence suppliers often instrument internal applications whose usage data is as sensitive as the application's own records. For them, a hosted analytics product is a non-starter regardless of its features. InsightClickIQ is built to run where the data is: on Oracle Cloud Infrastructure, on servers you own, or on a network with no outbound route, with the same container image and the same console as every other deployment.
This post covers both homes together, because they differ in fewer places than you might expect, and those places are the useful part.
Four references change
Everything that varies by environment in InsightClickIQ is a reference in configuration, resolved by the shared platform library. That is why there is no “OCI edition” or “on-prem edition”:
| Setting | Oracle Cloud (OCI) | On-premises |
|---|---|---|
| Platform build | INSIGHT_PLATFORM=oci (also detected from a resource principal) | INSIGHT_PLATFORM=local |
| Database | OCI Database with PostgreSQL; INSIGHT_DATABASE_URL | Postgres 16, with Patroni for high availability |
| Object store | oci://namespace/bucket — Object Storage, resource or instance principal | s3+http://minio:9000/clickiq — MinIO or Ceph through the S3 code path |
| Secrets | oci-vault://ocid1.vaultsecret… | file:///run/secrets/pg, vault://secret/… (HashiCorp KV v2) or env://VAR |
| Model | OCI Generative AI: INSIGHT_LLM_PROVIDER=oci plus a compartment id | Any OpenAI-compatible endpoint (vLLM, Ollama, LM Studio) via INSIGHT_LLM_BASE_URL, or none: CLICKIQ_AI=false |
| Events at large scale | Self-managed ClickHouse on Compute or OKE | ClickHouse OSS (24.8 verified) |
On Oracle Cloud
Database and bucket
OCI Database with PostgreSQL runs the schema as it is: row-level security on the
organization, the event table in monthly partitions, sessions, people and console content
beside it. Start at 2 OCPU for the small tier. Create the application role as an ordinary
login (NOSUPERUSER NOBYPASSRLS) so the policies bind it, and give it the role
defaults the project ships: statement_timeout = 30s, work_mem = 64MB.
Replay bodies and report PDFs go to Object Storage through an oci:// ref. The
store authenticates with a resource principal or instance principal when it runs inside
OCI, falling back to ~/.oci/config on a workstation, so there is no key in the
container's environment. The Postgres password sits in OCI Vault and is read by its OCID.
The model
With INSIGHT_LLM_PROVIDER=oci the AI features call OCI Generative AI. The
provider needs INSIGHT_OCI_COMPARTMENT_ID; the endpoint defaults to the Chicago
region and the chat model to cohere.command-r-plus unless you name another. The
model plans validated query specifications and writes narratives around results the engine
already computed; it never writes SQL and never sees raw events, so which model you choose
changes the wording, not the numbers.
No managed ClickHouse
This is the one real gap on OCI. AWS, Azure and Google Cloud all offer ClickHouse Cloud; OCI does not. Below about 100 million events a month that does not matter, because Postgres with partitions carries the event table. Above it, plan to run ClickHouse yourself on Compute or OKE. Autonomous Data Warehouse is the alternative people suggest, and it would need its own dialect in the query engine, which is not built.

On-premises
The project's compose file is the template for a pilot: Postgres 16 and the API on one machine, with a ClickHouse 24.8 service behind a profile for when you need it. The API image is two-stage: the build stage needs read access to the platform packages, passed as a build secret that never becomes a layer, and the runtime stage has no compiler, no git and runs as an unprivileged user. For an isolated network, build the image where it can reach the package repository, then move it in through your registry.
| Concern | On-premises answer |
|---|---|
| High availability | Patroni in front of Postgres 16; the API reconnects through whatever address your HA layer exposes. A connection pooler (PgBouncer) is safe in transaction mode, because the tenant is set per transaction. |
| Object store | MinIO or Ceph through the same S3 client as AWS, with an s3+http:// or s3+https:// endpoint. Access keys are secret refs (INSIGHT_S3_ACCESS_KEY_REF), not values. |
| Secrets | A mounted file, HashiCorp Vault KV v2, or an environment variable. Rows in the database never hold a secret value, only a ref. |
| The SDK | Served by the API itself at /sdk/clickiq.js from inside the image. Nothing is loaded from a public CDN. |
| Country | From an X-Country header your proxy sets, a MaxMind file mounted as CLICKIQ_GEOIP_DB, or the browser's time zone. No lookup service. |
| Backups | Your Postgres backup regime, with point-in-time recovery, plus bucket replication only if replays must survive a site loss. Most teams accept re-recording. |
When there is no model
The question an air-gapped buyer asks first is whether “AI-native” means “broken without the internet”. It does not, because of how the AI is built. Every number in the product comes from the query engine, not the model. The model has two jobs: choosing which validated queries to run for a question, and putting computed results into words. Both have a rules path.
| Surface | With a model | With CLICKIQ_AI=false |
|---|---|---|
| Insight strip on every screen (17 surfaces) | A narrative, findings and questions worded by the model from computed facts | A rules template per surface: ±20% changes flagged up or down, rising errors or rage clicks as risks |
| Signals | Detected statistically; the model writes the narrative and recommendation | Detected the same way; a rule per kind writes them |
| Weekly digest | A headline and paragraph from the real KPI deltas and movers | The same facts composed by rule |
| Investigations | Many sessions summarised and clustered into themes with evidence | Grouped by outcome and dominant problem: rage element, error, dead click, exit page |
| Agent playbooks | A tool-using loop chooses its next step | The playbook's fixed plan runs the same tools; findings read off the results |
| Ask | Plans queries from the question | A rule-based planner answers the common questions |

A middle path is common: a model on your own hardware behind an OpenAI-compatible API. Set
INSIGHT_LLM_PROVIDER=openai and INSIGHT_LLM_BASE_URL at a vLLM or
Ollama endpoint inside the network. Smaller local models word things less well; because they
only word computed results, they cannot make the numbers wrong, and any answer that fails
validation (unknown finding kinds, links to routes that do not exist) is replaced by the rules
reading.
Chat boxes, summaries and recommendations that depend on a hosted model, leaving empty panels and spinners when it is unreachable.
Every AI surface returns the same shape from its rules path, badged “Rules”. Charts, signals, impact estimates, journeys, zones and form analysis are computed exactly as before.
Sizing a pilot
What the security review will check
- Input values never leave the browser. Form analytics sends lengths, counts and
timings; replay masks every input by default;
[data-private]text is masked and[data-clickiq-block]elements are excluded entirely. - The write key is public by design. It can add events to one project, never read them, and it can be rotated from the project page. Allowed origins restrict which sites may send.
- Erasure is a single call.
DELETE /api/people/{id}removes a person, every id they were seen under, their sessions, events and replay objects. - Tenancy is enforced twice. Routes scope every query, and Postgres row-level security binds the application role. On a self-hosted ClickHouse, which has no RLS, the engine refuses to run any statement without an organization predicate, and the tests assert it on every generated statement.

What is not here yet
There is no managed ClickHouse on OCI, so the large tier means operating ClickHouse yourself. Daily rollup tables are on the storage roadmap and not shipped; the warehouse export (Parquet or NDJSON to oci://, MinIO or Ceph) has shipped. Server-side PDF rendering needs headless Chromium in the image; without it the console prints reports from the browser.
An air-gapped install loses the model's wording. It keeps every number, every signal, every replay and every finding.


