google/cloud-bigquery-reservation
Idiomatic PHP client for Google BigQuery Reservation. Install with composer require google/cloud-bigquery-reservation. Supports REST over HTTP/1.1 and gRPC, with authentication and debugging guides. Part of Google Cloud PHP and generally available.
Architecture fit. This is a control-plane SDK, not a data-plane SDK. It manages BigQuery slot capacity — reservations, capacity commitments, assignments, autoscale settings, BI reservations — and never touches query execution. For a TPM this reframes the decision entirely: the package has no place in a request path, a user-facing transaction, or a latency-sensitive flow. It belongs in one of three places:
| Use case | Fit | Notes |
|---|---|---|
| FinOps / cost-governance automation (autoscale tuning, slot reallocation) | Strong | Highest-value use; the reason to adopt at all |
| Multi-tenant BigQuery platform (provision a reservation per tenant/env) | Strong | Usually Terraform-first; PHP fills the imperative gaps |
| Incident tooling (move assignments, inspect replication/failover status) | Moderate | Valuable but must be read-mostly and operator-gated |
| Ad-hoc reporting / dashboards of slot usage | Weak | Use Cloud Monitoring / INFORMATION_SCHEMA, not this API |
Architecturally it is a thin generated GAPIC surface — typed request/response classes over gRPC and REST — with no business logic, no caching, no retry policy worth relying on, and no domain modelling. Treat it as a managed infrastructure dependency, not a library you build on. If your design has more than a handful of call sites, you have a seam problem, not a package problem.
Integration feasibility. Technically trivial: composer require google/cloud-bigquery-reservation, Application Default Credentials, and it drops cleanly into Laravel's container as a singleton ReservationServiceClient. The friction is entirely operational, not syntactic:
ext-grpc and the protobuf C extension in every runtime image. On managed PHP hosts, shared cgroups, or some serverless runtimes this is unavailable — plan for REST as the default and reserve gRPC for batch tooling where you control the image.bigquery.reservations.*) is admin-tier; a leaked key can destroy or re-commit your slot capacity.google-cloud-php monorepo. The counter-risk is the mirror image: you get Google's release discipline but no community escape hatch — no Stack Overflow corpus, no third-party wrappers, no blog posts. Ramp-up depends on Google's Cloud docs, not PHP docs.Technical risk.
| Risk | Severity | Why it matters to a TPM | Mitigation |
|---|---|---|---|
| Financial blast radius | High | Capacity commitments are billing instruments. A buggy automation that creates or extends a commitment is a spend incident, not an outage. | Hard cap on commitment creation in app code; commitments stay in Terraform/manual approval |
| Credential exposure | High | Admin-tier IAM key in a Laravel app is a standing liability | Workload identity federation; no key files in app images |
| Version churn / enum drift | Medium | Frequent minor releases add proto fields and enum values. Safe on the wire; unsafe if you match exhaustively on scaling modes or assignment types |
Pin ^2.x; always include a default arm in enum switches |
| v2 breaking surface | Medium | v2.0.0 broke the generated surface (new client surface went GA in 1.3.0, old surface deprecated, removed in v2). Older tutorials and samples are stale | Pin majors; don't copy pre-2023 snippets |
| gRPC runtime availability | Medium | Image/base-host constraint discovered late = rework | Decide REST vs gRPC at the spike, not at deploy |
| No first-class Laravel binding | Low | No published service provider | 30 lines of your own; accept it |
Key questions to resolve before committing.
ext-grpc, or are we committing to REST?Stack fit. Framework-agnostic; a plain Composer package with PSR-4 autoloading. It fits Laravel 10/11/12 and Symfony equally, and requires a modern PHP runtime (the v2.1.1 release explicitly added PHP 8.4 compatibility, so 8.1–8.4 is a safe band). There is no config/*.php to publish, no facade, no migration — integration is binding a client and writing a repository class around it. That is roughly a one-day task for a mid-level engineer, and it is the entire code cost.
Recommended placement. Resist the temptation to expose this broadly. The defensible pattern is a single wrapper service with two methods — a read-side that hydrates a cached snapshot of reservation state, and a write-side that is queue-dispatched, audited, and permission-gated:
App\Services\BigQuery\ReservationRepository (wraps ReservationServiceClient)
App\Jobs\SyncBigQueryReservationState (read, scheduled)
App\Jobs\ApplyReservationScaling (write, queued, approved)
App\Console\Commands\ReservationAudit (drift report vs Terraform)
Bind the client as a singleton in a service provider; inject the repository, never the client. This gives you one place to change when the generated surface shifts between majors, and one place to put an audit log.
Migration path. Most organisations will find slot capacity already managed by Terraform (google_bigquery_reservation, google_bigquery_capacity_commitment) or the console. Do not migrate that. Coexistence is the correct end state:
max_slots adjustments, temporary per-tenant reservations, assignment moves during incident response, BI reservation lookups. These are the changes that either can't wait for a Terraform PR or don't justify one.Compatibility notes. Pin ^2.0. Be aware that:
credentials client option is deprecated (v2.5.0) in favour of ADC-only flows — do not build credential-injection plumbing around it.Autoscale.current_slots can legitimately exceed max_slots after a user lowers the cap; do not treat that as an error condition in validation logic.Sequencing (suggested 4–6 weeks of part-time effort).
| Phase | Deliverable | Exit criteria |
|---|---|---|
| 0. Spike (2–3 days) | Client bound, one getReservation call succeeding from the target runtime |
Confirms ADC path, REST vs gRPC, PHP image viability |
| 1. Read-side (1 week) | Repository + scheduled sync job + audit command | Drift report runs nightly; zero write permissions granted |
| 2. Guardrails (1 week) | Audit logging, spend caps, approval gate design | A failed job cannot create or extend a commitment |
| 3. Write path (1–2 weeks) | Scoped autoscale/assignment operations behind approval | Rollback procedure rehearsed in a non-prod project |
| 4. Handover | Runbook, credential rotation, on-call notes | Platform team owns it, not the app team |
Maintenance. Code maintenance is near zero — the package is generated and you own ~200 lines of wrapper. Dependency maintenance is not zero: this component ships inside the google-cloud-php monorepo and releases roughly every two weeks (v1.0.3 → v2.10.3 across the visible history), including protobuf upgrades (v25.7 → v31.0 in v2.6.2) and periodic PHP-version compatibility work. Budget a monthly Composer update slot and a PHP-version-window review with each framework upgrade. The failure mode to avoid is a two-year dependency freeze that surfaces as an emergency PHP 9 migration.
Support. Support does not route to this repository. Per the README, all issues go to googleapis/google-cloud-php, and the component is GA — meaning no backwards-incompatible changes in minor/patch. The practical SLA is your Google Cloud support contract, not the library. That is fine, but a TPM should set the expectation explicitly: if the client misbehaves, the escalation path is a Cloud support case, and library-level GitHub response times should not be assumed.
Scaling. This is an administrative API with admin-tier quotas — it is not built for high QPS and should never sit on a hot path. Realistic volumes are tens to low hundreds of calls per hour at most. Design accordingly: cache reservation metadata for minutes rather than seconds, batch reads, and prefer Cloud Monitoring or INFORMATION_SCHEMA for slot-usage telemetry — this API tells you the configuration of capacity, not its consumption. Confusing the two is the most common architectural error with this package.
Failure modes to design for.
| Failure | Observable | Blast radius | Handling |
|---|---|---|---|
RESOURCE_EXHAUSTED / quota |
ApiException with quota reason |
Automation stalls, config drift accumulates | Exponential backoff; alert on repeated failure |
PERMISSION_DENIED after IAM change |
ApiException on otherwise-valid call |
Silent automation outage | IAM propagation lag is real; retry window of minutes, not seconds |
| Commitment created in error | Billing anomaly, not a log line | Financial; often non-cancellable for the term | Approval gate + hard cap is the only real control |
| Autoscale oscillation | Slot cost whipsaw | Cost variance, query queuing | Rate-limit write ops; require a minimum dwell time between changes |
| Assignment moved during failover | Confusing state; replication_status / soft_failover_start_time populated |
Query routing surprises | Treat replication_status as read-only telemetry; block writes during failover |
| Credential expiry / rotation miss | All calls 401 | Full automation outage | Workload identity federation; alert on auth failure rate |
Ramp-up. Two separate curves, and the TPM should plan for the second, not the first:
TPM verdict in one line: adopt it narrowly and deliberately — for read-side drift detection and gated, low-frequency write automation — while keeping committed capacity in Terraform, and treat the credential path and the financial blast radius, not the code, as the things to govern.
How can I help you explore Laravel packages today?