If you’re a US-based hobbyist, consultant, or small-batch hardware developer, PCB manufacturing has just changed a bit. Back in 2018 when the first batch of Chinese tariffs were introduced we got hit with a surprise bill and an import nightmare (well minor inconvenience but it felt dramatic at the time). Those tariffs landed during a government shutdown and a CBP computer glitch so our boards ended up doing two laps of the globe before we got them. I use a lot of 2 layer boards as I prefer them to just about any amount of hand-wiring. With the various price cliffs that have been introduced I was interested in what the most cost effective way to get boards are and maybe to justify an SV2 Pro. That’s a joke but The ION Prototyping lab does have a V-One, maybe it’s time to learn how to use it!
This post visualizes the total cost difference between OshPark (domestic) and two popular China-based fabs — PCBWay and JLCPCB — for small 2-layer boards, and gives a basic overview of the various pricing cliffs.
If you’ve been ordering batches of boards and assemblies under $800 then you have had a cheap and easy life thanks to the (now dead) de minimus exemption A.K.A Section 321. Your package would pass through customs quickly and easily, with no tariff due. Once you exceeded the $800 limit then a 25% tariff became due and you’d need to write DHL a check and you need to actually deal with customs. DHL does a great job as a broker but they’ll only front so much of the tariff. Once the order value exceeds DHL’s simplified processing limits, you should probably be talking to a customs broker. For orders under $2500 there is a simplified process with a full customs process above that.
Postal shipments have a minimum tariff to simplify processing packages but the commercial carriers just calculate the tariff.
For JLCPCB and PCBWay I assume DHL shipping and the 55% tariff in place as of 2025-05-15. I am getting the DHL processing fees from their online calculator.
Keep in mind: if duties aren’t paid promptly, additional fees will be added to the bill.
Declared Value | Duties | Fees | DHL Fee | Total Landed Cost |
---|---|---|---|---|
$100 | $55 | $2.62 | $17 | $174.62 |
$1,000 | $550 | $2.62 | $17 | $1,569.62 |
$10,000 | $5,500 | $34.64 | $110.69 | $15,645.33 |
The exact fee breakdown is included at the end of this post.
We analyzed board pricing across three suppliers for two configurations using the estimated DHL costs.
I’ve gotten dozens of boards from each of these suppliers with no serious complaints.
This plot looks at the cheapest 2-layer board offered. If you need a wiring board this is reasonable but puts OshPark at a disadvantage in cost as they are using more expensive plating and board materials.
Supplier | Finish | FR4 TG | Min Drill Size | Trace/Space | Vias |
---|---|---|---|---|---|
OshPark | ENIG | TG175 | 0.254 mm | 6/6 mil | Tented |
PCBWay | HASL | TG150 | 0.30 mm | 6/6 mil | Tented |
JLCPCB | HASL | TG140 | 0.30 mm | 6/6 mil | Tented |
This plot looks at the the Chinese fabs 2-layer boards that have comparable specs to OshPark. The ENIG is great for aesthetics but these are 2-Layer boards, it’s unlikely you’re placing fine pitch parts on them. OshPark has 3-5um gold plating which can’t be changed whereas PCBWay offers 1, 2, or 3um options and JLCPCB offers 1 or 2 um. The different thicknesses can be visually distinguished.
While the previous plot compared the cheapest 2-layer options, it’s a bit unfair to OshPark. Their default spec includes ENIG finish and TG175 material — things you’d need to pay extra for at JLCPCB or PCBWay.
This second comparison levels the playing field.
Supplier | Finish | Gold Thickness | FR4 TG | Min Drill Size | Trace/Space | Via Treatment |
---|---|---|---|---|---|---|
OshPark | ENIG | 3–5 µm | TG175 | 0.254 mm | 6/6 mil | Tented |
PCBWay | ENIG | 3 µm | TG175 | 0.25 mm | 6/6 mil | Tented |
JLCPCB | ENIG | 2 µm | TG140 | 0.25 mm | 6/6 mil | Plugged |
If you’re ordering low total board area and don’t need custom solder mask colors, OshPark avoids the tariff headache and is often cheaper. For projects with larger total board areas, imported fabs like JLCPCB and PCBWay win on price — even with the increased tariff.
If you want ENIG and a high TG FR4 then OshPark is competitive up to significant volumes. Note that OshPark only offers 2x solder mask varieties where as the others offer several colors for a fairly nominal fee.
Have thoughts, tricks for minimizing tariffs, or manufacturing insights? Contact me!
EXPORT TARIFF CODE | 8534.00.9000 |
IMPORT TARIFF CODE | 8534.00.0040 |
Duties Paid By | Receiver |
Shipper is a | Business |
Receiver is a | Business |
Duty Description | Rate | Amount (USD) |
---|---|---|
Additional Duty (Section 301) | 25% Total Value of Product | $25.00 |
Custom Duty | 0% Total Value of Product | $0.00 |
Additional Duty (Executive Order/IEEPA - Reciprocal Tariff) | 10% Total Value of Product | $10.00 |
Additional Duty (Executive Order/IEEPA) | 20% Total Value of Product | $20.00 |
Fee Description | Rate | Amount (USD) |
---|---|---|
Harbour Maintenance Fees | 0 | $0.00 |
Merchandise Processing Fees | USD 2.62 | $2.62 |
DHL Fee Description | Rate | Amount (USD) |
---|---|---|
Duty Tax Processing | DHL Express Rate | $17.00 |
Landed Cost for $100: $174.62
Duty Description | Rate | Amount (USD) |
---|---|---|
Additional Duty (Section 301) | 25% Total Value of Product | $250.00 |
Custom Duty | 0% Total Value of Product | $0.00 |
Additional Duty (Executive Order/IEEPA - Reciprocal Tariff) | 10% Total Value of Product | $100.00 |
Additional Duty (Executive Order/IEEPA) | 20% Total Value of Product | $200.00 |
Fee Description | Rate | Amount (USD) |
---|---|---|
Harbour Maintenance Fees | 0 | $0.00 |
Merchandise Processing Fees | USD 2.62 | $2.62 |
DHL Fee Description | Rate | Amount (USD) |
---|---|---|
Duty Tax Processing | DHL Express Rate | $17.00 |
Landed Cost for $1000: $1,569.62
Duty Description | Rate | Amount (USD) |
---|---|---|
Additional Duty (Section 301) | 25% Total Value of Product | $2500.00 |
Custom Duty | 0% Total Value of Product | $0.00 |
Additional Duty (Executive Order/IEEPA - Reciprocal Tariff) | 10% Total Value of Product | $1000.00 |
Additional Duty (Executive Order/IEEPA) | 20% Total Value of Product | $2000.00 |
Fee Description | Rate | Amount (USD) |
---|---|---|
Harbour Maintenance Fees | 0 | $0.00 |
Merchandise Processing Fees | (0.3464% Total Value of Product) — Minimum $32.71, Maximum $634.62 | $34.64 |
DHL Fee Description | Rate | Amount (USD) |
---|---|---|
Duty Tax Processing | DHL Express Rate | $110.69 |
Landed Cost for $10000: $15,645.33
from matplotlib import pyplot as plt
import numpy as np
oshpark_price_lv = 5/3 # $5/sqin for 3x boards
oshpark_price_hv = 1 # $1/sqin
# 0.25mm Hole, all ENIG, 6/6 mil traces
# TG175, ENIG 3um
pcbway_prices_tg150_hasl = (
(5, 10, 21),
(15, 14.8, 21),
(100, 42, 21),
(200, 52, 25),
(300, 59, 25),
(500, 86, 27),
(1000, 180, 41),
)
# TG175, ENIG 3um
pcbway_prices_tg175_enig = (
(5, 116.71, 21),
(15, 117.21, 21),
(100, 141.19, 21),
(200, 154.34, 25),
(300, 162.61, 25),
(500, 194.23, 27),
(1000, 292.3, 41),
)
jlcpcb_prices_tg140_hasl = (
(5, 2.1, 23),
(20, 5.4, 23),
(50, 10.7, 23),
(100, 13.1, 23),
(200, 12.1, 32),
(300, 23, 32),
(500, 32.8, 40),
(1000, 57.3, 56),
)
# TG140, ENIG 2um, plugged vias
jlcpcb_prices_tg140_enig = (
(5, 80.92, 23),
(20, 84.95, 23),
(50, 90.35, 23),
(100, 95.07, 23),
(200, 104.81, 32),
(300, 114.35, 32),
(500, 133.62, 40),
(1000, 181.72, 56),
)
oshpark_shipping = 0
tarriff_fraction = 0.55
fees = 11.78 # Maximum Customs surcharge under $2500
def calculate_dhl_fees(duty):
return 1.31 + max([17, 2/100*duty])
def get_osh_prices(area):
unit_price = oshpark_price_lv
if area > 100:
unit_price = oshpark_price_hv
return area*unit_price + oshpark_shipping
def get_imported_prices(price_matrix):
areas = [x for x, *_ in price_matrix]
prices = [price*(1+tarriff_fraction) +
fees + shipping + calculate_dhl_fees(price*tarriff_fraction)
for x, price, shipping in price_matrix]
return areas, prices
xlims = [0, 350]
ylims = [0, 350]
x = np.linspace(3, 1000, 50)
fig, ax = plt.subplots()
ax.plot(x, [get_osh_prices(pt) for pt in x], color="purple", label="Oshpark (ENIG, TG175)")
ax.plot(*get_imported_prices(pcbway_prices_tg150_hasl), 'x--', color="green", label="PCBWay (HASL, TG150)")
ax.plot(*get_imported_prices(jlcpcb_prices_tg140_hasl), 'x--', color="blue", label="JLCPCB (HASL, TG140)")
ax.set_title("OshPark vs. Imported Prices for Cheapest 2-Layer\n1x1 inch PCB Offering (May 15, 2025)")
ax.set_xlabel("Total Board Area (in$^2$)")
ax.set_ylabel("Total Price w/ Tariff (USD)")
ax.set_xlim(xlims)
ax.set_ylim(ylims)
fig.legend(loc=(0.5, 0.15))
x = np.linspace(3, 1000, 50)
fig, ax = plt.subplots()
ax.plot(x, [get_osh_prices(pt) for pt in x], color="purple", label="Oshpark (ENIG 3-5um, TG175)")
ax.plot(*get_imported_prices(pcbway_prices_tg175_enig), 'x--', color="green", label="PCBWay (ENIG 3um, TG175)")
ax.plot(*get_imported_prices(jlcpcb_prices_tg140_enig), 'x--', color="blue", label="JLCPCB (ENIG 2um, TG140)")
ax.set_title("OshPark vs. Imported Prices for Comparable 2-Layer\n1x1 inch PCB Offering (May 15, 2025)")
ax.set_xlabel("Total Board Area (in$^2$)")
ax.set_ylabel("Total Price w/ Tariff (USD)")
ax.set_xlim(xlims)
ax.set_ylim(ylims)
fig.legend(loc=(0.5, 0.15))