Skip to main content

Change an Organization's Tier from Trial to Enterprise

This page is for operators of a self-hosted Permit Platform whose organization still shows the Trial tier. It explains how the installer sets the tier, how to check that the installer did it, and how to change the tier in the PostgreSQL database by hand.

The migrations job, permit-migrations, sets every organization to Enterprise tier each time the installer runs, on first installation and on every upgrade. The job sets both tier fields:

  • is_enterprise = true
  • usage_limits.billing_tier = "enterprise"

In most installations, no manual change is needed. To confirm that the job updated your organizations, search its logs while the job still exists in the namespace:

  • Enterprise tier applied to <N> organization(s) means the update ran.
  • Enterprise tier update skipped: <error> means the update failed and the job continued. Fix the error, or change the tier manually as described in Change the tier manually.

Run kubectl logs -n permit-platform job/permit-migrations | grep -i "enterprise tier" to find these messages.

Tier fields in the database

The organization's tier is stored in two columns of the v2.v2_organization table. Update both columns to change the tier.

ColumnTypeControls
is_enterprisebooleanEnterprise feature access and the tier badge
usage_limits.billing_tierstring inside a JSONB objectBilling status and the trial countdown message

Prerequisites

  • kubectl access to the namespace where Permit Platform runs. The commands use the default namespace, permit-platform.
  • A running PostgreSQL pod in that namespace.
  • A recent database backup. See Create backups.

Change the tier manually

Use this procedure when the migrations job didn't update an organization, for example because the update was skipped or the installation predates the automatic update.

1. Find the PostgreSQL pod

List the pods and copy the name of the postgres pod:

kubectl get pods -n permit-platform | grep postgres

The output looks like this:

postgres-c94f7f6fd-tj55t 1/1 Running 0 2d

2. Check the organization's current tier

Replace <postgres-pod-name> with the pod name and <org-name> with the organization name:

kubectl exec -n permit-platform <postgres-pod-name> -- \
psql -U permit -d permit -c \
"SELECT id, name, is_enterprise, usage_limits FROM v2.v2_organization WHERE name = '<org-name>';"

Example output:

id | name | is_enterprise | usage_limits
--------------------------------------+----------+---------------+-------------------------------------------------------
8cdcc192-0ba3-472f-8691-87d765af715f | gke-test | f | {"mau": 5000, "tenants": 50, "billing_tier": "trial"}

The organization is on Trial tier when is_enterprise is f (false) and usage_limits contains "billing_tier": "trial". Copy the id value for the next step.

3. Set the organization to Enterprise tier

Update both fields in one statement. Replace <organization-uuid> with the id from the previous step:

kubectl exec -n permit-platform <postgres-pod-name> -- \
psql -U permit -d permit -c \
"UPDATE v2.v2_organization
SET is_enterprise = true,
usage_limits = jsonb_set(usage_limits, '{billing_tier}', '\"enterprise\"')
WHERE id = '<organization-uuid>';"

For example:

kubectl exec -n permit-platform postgres-c94f7f6fd-tj55t -- \
psql -U permit -d permit -c \
"UPDATE v2.v2_organization
SET is_enterprise = true,
usage_limits = jsonb_set(usage_limits, '{billing_tier}', '\"enterprise\"')
WHERE id = '8cdcc192-0ba3-472f-8691-87d765af715f';"

PostgreSQL confirms that one row changed:

UPDATE 1

UPDATE 0 means no organization has that id. Check the value and run the statement again.

4. Verify the change in the database

Run the query from step 2 again:

kubectl exec -n permit-platform <postgres-pod-name> -- \
psql -U permit -d permit -c \
"SELECT id, name, is_enterprise, usage_limits FROM v2.v2_organization WHERE name = '<org-name>';"

Expected output:

id | name | is_enterprise | usage_limits
--------------------------------------+----------+---------------+------------------------------------------------------------
8cdcc192-0ba3-472f-8691-87d765af715f | gke-test | t | {"mau": 5000, "tenants": 50, "billing_tier": "enterprise"}

The change is saved when is_enterprise is t (true) and usage_limits contains "billing_tier": "enterprise".

5. Verify the change in the Permit frontend

Hard refresh the Permit frontend in your browser. The tier badge shows Enterprise, and the trial countdown message is gone. If the page still shows the Trial tier, see Changes not visible in the frontend.

Set the PRO tier instead

To set an organization to PRO tier, set is_enterprise to false and billing_tier to "pro":

kubectl exec -n permit-platform <postgres-pod-name> -- \
psql -U permit -d permit -c \
"UPDATE v2.v2_organization
SET is_enterprise = false,
usage_limits = jsonb_set(usage_limits, '{billing_tier}', '\"pro\"')
WHERE id = '<organization-uuid>';"
The installer resets PRO organizations to Enterprise

The migrations job sets every organization whose tier isn't Enterprise to Enterprise. The next installer run or upgrade changes a PRO organization back to Enterprise.

Database field reference

is_enterprise (boolean)

ValueTier
trueEnterprise
falsePRO or Trial, depending on usage_limits.billing_tier

usage_limits (JSONB)

usage_limits holds the organization's limits and its billing tier. The comments in the example explain each field:

{
"mau": 5000, // Monthly Active Users limit
"tenants": 50, // Tenant limit
"billing_tier": "trial" // Billing status: "trial", "pro", or "enterprise"
}

billing_tier accepts "trial", "pro", or "enterprise". The trial countdown message in the frontend depends on billing_tier.

Rules for editing the tier fields

  • Update both fields. If you change only is_enterprise, the trial countdown message stays.
  • Use lowercase tier values. Write "trial", "pro", and "enterprise" in lowercase.
  • Back up first. A wrong WHERE clause changes other organizations. See Create backups.
  • Refresh the browser. The frontend can show the old tier until you hard refresh or sign in again.

Troubleshooting

Changes not visible in the frontend

  • Hard refresh the browser: Ctrl+Shift+R on Windows and Linux, Cmd+Shift+R on macOS.
  • Clear the browser cache.
  • Sign out and sign in again.

Organization not found

List all organizations to find the correct name or id:

kubectl exec -n permit-platform <postgres-pod-name> -- \
psql -U permit -d permit -c \
"SELECT id, name, key, is_enterprise FROM v2.v2_organization;"

Permission denied

A kubectl exec permission error means your Kubernetes user can't exec into pods in the namespace. Ask your cluster administrator for pods/exec access. A PostgreSQL permission error means the database user in the command lacks write access to v2.v2_organization.

Database schema reference

Table: v2.v2_organization

ColumnTypeDescription
iduuidPrimary key
nametextOrganization name
keytextOrganization key
is_enterprisebooleanEnterprise tier flag
usage_limitsjsonbUsage limits and billing tier
settingsjsonbAdditional settings
created_attimestamp with time zoneCreation time
updated_attimestamp with time zoneLast update time

Related pages