WooCommerce shipping has three layers: zones decide who gets which methods based on the customer's address, methods decide how a shipment is priced, and classes let you charge different rates for different products within the same method. Get the zones and classes right first. Only reach for a live-rates plugin (real-time carrier quotes from UPS, FedEx, or USPS) once flat or table rates genuinely can't represent your costs, because live-rates plugins add an external API call to every cart and checkout page load.
Zones: who sees what
A shipping zone is a named group of regions (countries, states, or ZIP/postcode ranges) with its own list of shipping methods. WooCommerce checks zones top to bottom and uses the first match, so order matters. Set this up under WooCommerce → Settings → Shipping:
- Create specific zones first (a single state or metro area) and put them above broader ones (a whole country), since only the first matching zone applies.
- Add a catch-all zone last, with no location restrictions, so customers outside your defined zones still get a shipping option instead of a dead checkout.
- Each zone can carry multiple methods (for example, flat rate and local pickup together) and the customer picks one at checkout.
If a customer sees no shipping options at checkout, it's almost always a zone gap: their address doesn't match any zone you've defined, including the catch-all.
Methods: how it's priced
WooCommerce ships with a few built-in methods, and most stores can run entirely on these without a plugin:
- Flat rate - one price per zone, optionally adjusted per shipping class or per item.
- Free shipping - usually gated behind a minimum order amount or a coupon.
- Local pickup - no shipping cost, customer collects the order.
Flat rate is the workhorse. You can set a base cost for the zone and then add class-based costs on top (see below), which covers a surprising amount of real-world pricing without any add-on.
Table rate and carrier-calculated methods
When flat rate can't express your pricing, for example, cost that scales with weight brackets, cart total, or distance, you're choosing between a table rate plugin (rules you define yourself, no external API) and a live-rates plugin (real-time quotes pulled from a carrier's API at checkout). Table rate is the middle ground: more flexible than flat rate, but still fully under your control and with no added latency, since nothing leaves your server.
Classes: different rates for different products
A shipping class is a label you assign to products (Products → [product] → Shipping, or in bulk from the product list) that a shipping method can then price differently. Common uses:
- Oversized or heavy items that cost more to ship than a standard parcel.
- Fragile items that need special packaging factored into the rate.
- Digital or non-shippable products excluded from shipping calculations entirely.
Define classes under WooCommerce → Settings → Shipping → Shipping classes, then set per-class costs inside each flat rate method's settings. A cart with mixed classes uses whichever calculation rule you've picked (highest class cost, sum of all classes, or per-class per-item) - check that setting once and confirm it matches what you actually want, because the default isn't always obvious from the checkout preview alone.
When you need a live-rates plugin
Reach for a live-rates plugin only when one of these is true:
- You ship items where cost genuinely varies by exact weight, dimensions, and destination in a way table rate can't approximate closely enough.
- You need customers to choose between carrier service levels (ground, 2-day, overnight) with real quoted prices, not your own estimate.
- Shipping cost is a large enough share of order value that a flat-rate mismatch is costing you money on every order, either you're overcharging and losing sales, or undercharging and eating the difference.
The tradeoff is real: every live-rates plugin calls an external carrier API on cart and checkout loads, which adds latency those pages didn't have before. Test checkout speed after installing one. If your store is already feeling sluggish, work through My WordPress site is slow first so you're not troubleshooting a new plugin and an existing performance problem at the same time.
Whichever method you choose, treat shipping changes like any other risky store change: build the new zone or method on a staging copy first, run a full test checkout including the shipping step, and only push to live once it works. See Using WordPress staging. This matters more for shipping than most settings, because a broken shipping calculation can silently block checkout entirely, and you won't know until a customer can't complete an order. The general performance and reliability practices in Running a WooCommerce store apply here too: caching stays store-safe automatically, but new plugins are still worth testing on staging before they touch live traffic.
Getting help
If shipping rates are calculating incorrectly and you've confirmed it's not a zone ordering or class assignment issue, or if a live-rates plugin is timing out and you're not sure whether it's the carrier API or your hosting, open a ticket from the portal under Support → New ticket. It's a real person, not a bot, and they can check server-side logs for API timeouts that wouldn't be visible from the WordPress admin alone.