
When managing Shared VPCs, most teams allocate dedicated IP subnets for each service project to keep...
When managing Shared VPCs, most teams allocate dedicated IP subnets for each service project to keep firewall rules simple, but this isolation often leads to poor IP utilization — it is not uncommon to see subnet IP utilization hovering in the low teens. On the other hand, using large shared subnets requires coordinating workload deployments to ensure there is enough internal IP address space for everyone. To optimize these shared networks, you need real-time visibility. The WITH_UTILIZATION query parameter on the Method: subnetworks.list | Compute Engine API solves this by returning the exact count of allocated and free IP addresses for each subnet IP range.
This capability is designed for query-time decisions. For example, if you need to deploy a GCE workload requiring 100 instances, you can search for a subnet with enough capacity. This query-time data comes directly from Google Cloud's internal IP allocator and includes both primary and secondary CIDR ranges.
To automate capacity checks before you deploy, you can script this check. The script below uses gcloud compute networks subnets list | Google Cloud SDK to grab the utilization data as JSON, and then uses jq to parse, filter, and sort the subnets based on your required capacity:
#!/bin/bash
# --- Configuration (Replace with your details) ---
PROJECT="<YOUR_PROJECT_ID>"
NETWORK_NAME="<YOUR_VPC_NETWORK_NAME>"
REGION="<YOUR_REGION>"
REQUIRED_IP_CAPACITY=100
echo "Searching $NETWORK_NAME in $REGION for subnets with >= $REQUIRED_IP_CAPACITY free IPs..."
echo "------------------------------------------------------------------------"
# Fetch subnets with utilization data, output as JSON, and pipe to jq
gcloud compute networks subnets list \
--project="$PROJECT" \
--network="$NETWORK_NAME" \
--regions="$REGION" \
--view=WITH_UTILIZATION \
--format=json | \
jq -r --argjson min_ips "$REQUIRED_IP_CAPACITY" '
[
.[] | {
name: .name,
cidr: .ipCidrRange,
# Safely extract totalFreeIp: if it is null, substitute "0" before converting to a number
free_ips: (.utilizationDetails.ipv4Utilizations[0].totalFreeIp // "0" | tonumber)
}
# Keep only the subnets that meet the minimum requirement
| select(.free_ips >= $min_ips)
]
# Sort ascending by free_ips, then reverse to get descending order
| sort_by(.free_ips)
| reverse
# Format the final output into clean, readable strings
| .[]
| "Subnet: \(.name) | CIDR: \(.cidr) | Free IPs: \(.free_ips)"
'
Let's list the configured subnets in our target region first:
~ gcloud compute networks subnets list \
--project="my-gcp-project" \
--format='table(name, region, network, ipCidrRange)'
NAME REGION NETWORK RANGE
subnet-a0 us-south1 vpc-a 10.0.0.0/28
subnet-a1 us-south1 vpc-a 10.0.1.0/28
subnet-a2 us-south1 vpc-a 10.0.2.0/28
subnet-a3 us-south1 vpc-a 10.0.3.0/28
subnet-a4 us-south1 vpc-a 10.0.4.0/28
subnet-a5 us-south1 vpc-a 10.0.5.0/24
subnet-a6 us-south1 vpc-a 10.0.6.0/25
subnet-a7 us-south1 vpc-a
subnet-a8 us-south1 vpc-a
subnet-a9 us-south1 vpc-a
Running the script returns only the subnets that can safely host our 100-instance workload:
~ bash gce-subnet-utilization.sh
Searching vpc-a in us-south1 for subnets with >= 100 free IPv4 addresses...
------------------------------------------------------------------------
Subnet: subnet-a5 | CIDR: 10.0.5.0/24 | Free IPs: 252
Subnet: subnet-a6 | CIDR: 10.0.6.0/25 | Free IPs: 124
When you request a subnet list with the utilization view, the API returns a utilizationDetails object. For a standard subnet with only a primary IPv4 address configured, the JSON payload looks like this:
"utilizationDetails": {
"ipv4Utilizations": [
{
"totalAllocatedIp": "4",
"totalFreeIp": "252"
}
]
}
Notice that the totalAllocatedIp is 4. In any primary IPv4 range, Google Cloud reserves four IP addresses for default routing and metadata, as detailed in the Subnets | Virtual Private Cloud - Google Cloud Documentation.
If you have secondary ranges configured (often used for GKE Pods), the API includes utilization metrics for each secondary range, identified by rangeName:
"utilizationDetails": {
"ipv4Utilizations": [
{
"totalAllocatedIp": "4",
"totalFreeIp": "124"
},
{
"rangeName": "a6-secondary",
"totalAllocatedIp": "0",
"totalFreeIp": "4096"
}
]
}
The API also breaks down IPv6 utilization if you are running dual-stack subnets. It tracks external instance IPs, load balancer endpoints, and internal IPv6 allocations separately:
"utilizationDetails": {
"externalIpv6InstanceUtilization": {
"totalAllocatedIp": { "high": "0", "low": "0" },
"totalFreeIp": { "high": "0", "low": "9223372036854775808" }
},
"externalIpv6LbUtilization": {
"totalAllocatedIp": { "high": "0", "low": "0" },
"totalFreeIp": { "high": "0", "low": "9223372036854775808" }
},
"internalIpv6Utilization": {
"totalAllocatedIp": { "high": "0", "low": "8589934592" },
"totalFreeIp": { "high": "0", "low": "18446744065119617024" }
}
}
WITH_UTILIZATION parameter works with both Method: subnetworks.get | Compute Engine and Method: subnetworks.list | Compute Engine.gcloud using --view=WITH_UTILIZATION, as documented in gcloud compute networks subnets list | Google Cloud SDK.tonumber in jq) before running any mathematical comparisons.Next time you are building a deployment pipeline, try integrating the WITH_UTILIZATION view. It is a simple way to programmatically ensure you have enough network headroom before kicking off a deployment.
aiMost of us have seen a coding agent fail to complete a task we know it can do. We just don't...
googlecloudWhen building Generative AI applications, developers often encounter a massive bottleneck: sequential...
discussI’ve been thinking about sharing some electronic circuit posts on Dev.to — small circuits, DIY...
agentsWhat nobody tells you about exporting your multi-agent prototype to a local workspace. Every...
agenticarchitectAutonomous agents are genuinely good at answering messy business questions. Give one an LLM and a set...
aiPR volume went up, ticket quality didn't, and the gap got filled with LLMs on both sides of the review: bots reviewing, bots replying, bots occasionally arguing with bots about priorities that only existed in a teammate's head. Our CEO named the actual problem, and it's bigger than code review.
Workflows from the Neura Market marketplace related to this Stable Diffusion resource