diff --git a/lib/plausible/billing/enterprise_plan.ex b/lib/plausible/billing/enterprise_plan.ex
index 65141098323636619f0af1119bb7b296a48296e1..cfae0d4ff7f2bcb85aad21ead11f6c65223c1aab 100644
--- a/lib/plausible/billing/enterprise_plan.ex
+++ b/lib/plausible/billing/enterprise_plan.ex
@@ -7,7 +7,8 @@ defmodule Plausible.Billing.EnterprisePlan do
     :paddle_plan_id,
     :billing_interval,
     :monthly_pageview_limit,
-    :hourly_api_request_limit
+    :hourly_api_request_limit,
+    :site_limit
   ]
 
   schema "enterprise_plans" do
@@ -15,6 +16,7 @@ defmodule Plausible.Billing.EnterprisePlan do
     field :billing_interval, Ecto.Enum, values: [:monthly, :yearly]
     field :monthly_pageview_limit, :integer
     field :hourly_api_request_limit, :integer
+    field :site_limit, :integer
 
     belongs_to :user, Plausible.Auth.User
 
diff --git a/lib/plausible/billing/enterprise_plan_admin.ex b/lib/plausible/billing/enterprise_plan_admin.ex
index 616eea5b66a055d6ea2d30eaf7e5bc21f1d4b227..08c396732863585c711bec2aec6d6a380c6c2a44 100644
--- a/lib/plausible/billing/enterprise_plan_admin.ex
+++ b/lib/plausible/billing/enterprise_plan_admin.ex
@@ -14,7 +14,8 @@ defmodule Plausible.Billing.EnterprisePlanAdmin do
       paddle_plan_id: nil,
       billing_interval: %{choices: [{"Yearly", "yearly"}, {"Monthly", "monthly"}]},
       monthly_pageview_limit: nil,
-      hourly_api_request_limit: nil
+      hourly_api_request_limit: nil,
+      site_limit: nil
     ]
   end
 
@@ -29,7 +30,8 @@ defmodule Plausible.Billing.EnterprisePlanAdmin do
       paddle_plan_id: nil,
       billing_interval: nil,
       monthly_pageview_limit: nil,
-      hourly_api_request_limit: nil
+      hourly_api_request_limit: nil,
+      site_limit: nil
     ]
   end
 
diff --git a/lib/plausible/sites.ex b/lib/plausible/sites.ex
index a57df0b487040baf940c6be6ca017742dbcb4f0f..555ee1088bbb52bbc35722917cd4a5efc21ac059 100644
--- a/lib/plausible/sites.ex
+++ b/lib/plausible/sites.ex
@@ -124,6 +124,17 @@ defmodule Plausible.Sites do
     )
   end
 
+  def count_owned_by(user) do
+    Repo.one(
+      from s in Plausible.Site,
+        join: sm in Plausible.Site.Membership,
+        on: sm.site_id == s.id,
+        where: sm.role == :owner,
+        where: sm.user_id == ^user.id,
+        select: count(sm)
+    )
+  end
+
   def owner_for(site) do
     Repo.one(
       from u in Plausible.Auth.User,
diff --git a/lib/plausible_web/email.ex b/lib/plausible_web/email.ex
index d2f6fee7bb9f2b269d2ecfdb43aea00449d93647..698282ab5b0fe293dde478b6b618ed2fb0223e83 100644
--- a/lib/plausible_web/email.ex
+++ b/lib/plausible_web/email.ex
@@ -128,7 +128,7 @@ defmodule PlausibleWeb.Email do
     })
   end
 
-  def enterprise_over_limit_email(user, usage, last_cycle) do
+  def enterprise_over_limit_email(user, usage, last_cycle, site_usage, site_allowance) do
     base_email()
     |> to("enterprise@plausible.io")
     |> tag("enterprise-over-limit")
@@ -136,7 +136,9 @@ defmodule PlausibleWeb.Email do
     |> render("enterprise_over_limit.html", %{
       user: user,
       usage: usage,
-      last_cycle: last_cycle
+      last_cycle: last_cycle,
+      site_usage: site_usage,
+      site_allowance: site_allowance
     })
   end
 
diff --git a/lib/plausible_web/router.ex b/lib/plausible_web/router.ex
index 233a814ce7dd7f8a8de215f23937b7efebcf4aef..0b95355343a6ca21eaae6fd07a6077fe9b8ca8af 100644
--- a/lib/plausible_web/router.ex
+++ b/lib/plausible_web/router.ex
@@ -41,7 +41,7 @@ defmodule PlausibleWeb.Router do
     plug PlausibleWeb.Firewall
   end
 
-  if Application.get_env(:plausible, :environment) == "dev" do
+  if Mix.env() == :dev do
     forward "/sent-emails", Bamboo.SentEmailViewerPlug
   end
 
diff --git a/lib/plausible_web/templates/email/enterprise_over_limit.html.eex b/lib/plausible_web/templates/email/enterprise_over_limit.html.eex
index 6fea4741b28a6e79d8c7aeedfb6f3f96e7341543..af82475e05f5b9248c346ffcb3b1fa84bf1696a0 100644
--- a/lib/plausible_web/templates/email/enterprise_over_limit.html.eex
+++ b/lib/plausible_web/templates/email/enterprise_over_limit.html.eex
@@ -1,8 +1,9 @@
-Automated notice about an account that has gone over their enteprise plan limit.
+Automated notice about an enterprise account that has gone over their limits. <br /><br />
 
-Customer email: <% @user.email %>
-Last billing cycle: <%= date_format(@last_cycle.first) %> to <%= date_format(@last_cycle.last) %>
-Usage: <%= PlausibleWeb.StatsView.large_number_format(@usage) %> billable pageviews
+Customer email: <%= @user.email %><br />
+Last billing cycle: <%= date_format(@last_cycle.first) %> to <%= date_format(@last_cycle.last) %><br >
+Pageview Usage: <%= PlausibleWeb.StatsView.large_number_format(@usage) %> billable pageviews<br />
+Site usage: <%= @site_usage %> / <%= @site_allowance %> allowed sites<br />
 
 --<br />
 <%= plausible_url() %><br />
diff --git a/lib/workers/check_usage.ex b/lib/workers/check_usage.ex
index a596b86dd321d9311d6ad32f2f81155ff3493a56..cf31aaeda4fba5598248b4428f33e4b15cf24366 100644
--- a/lib/workers/check_usage.ex
+++ b/lib/workers/check_usage.ex
@@ -50,38 +50,80 @@ defmodule Plausible.Workers.CheckUsage do
       )
 
     for subscriber <- active_subscribers do
-      allowance = Plausible.Billing.Plans.allowance(subscriber.subscription)
-      {last_last_month, last_month} = billing_mod.last_two_billing_months_usage(subscriber)
-      is_over_limit = last_last_month > allowance && last_month > allowance
+      if subscriber.enterprise_plan do
+        check_enterprise_subscriber(subscriber, billing_mod)
+      else
+        check_regular_subscriber(subscriber, billing_mod)
+      end
+    end
 
-      cond do
-        is_over_limit && subscriber.enterprise_plan ->
-          {_, last_cycle} = billing_mod.last_two_billing_cycles(subscriber)
+    :ok
+  end
 
-          template =
-            PlausibleWeb.Email.enterprise_over_limit_email(subscriber, last_month, last_cycle)
+  def check_enterprise_subscriber(subscriber, billing_mod) do
+    pageview_limit = check_pageview_limit(subscriber, billing_mod)
+    site_limit = check_site_limit(subscriber)
 
-          Plausible.Mailer.send_email_safe(template)
+    case {pageview_limit, site_limit} do
+      {{:within_limit, _}, {:within_limit, _}} ->
+        nil
 
-        is_over_limit ->
-          {_, last_cycle} = billing_mod.last_two_billing_cycles(subscriber)
-          suggested_plan = Plausible.Billing.Plans.suggested_plan(subscriber, last_month)
+      {{_, {last_cycle, last_cycle_usage}}, {_, {site_usage, site_allowance}}} ->
+        template =
+          PlausibleWeb.Email.enterprise_over_limit_email(
+            subscriber,
+            last_cycle_usage,
+            last_cycle,
+            site_usage,
+            site_allowance
+          )
 
-          template =
-            PlausibleWeb.Email.over_limit_email(
-              subscriber,
-              last_month,
-              last_cycle,
-              suggested_plan
-            )
+        Plausible.Mailer.send_email_safe(template)
+    end
+  end
 
-          Plausible.Mailer.send_email_safe(template)
+  defp check_regular_subscriber(subscriber, billing_mod) do
+    case check_pageview_limit(subscriber, billing_mod) do
+      {:over_limit, {last_cycle, last_cycle_usage}} ->
+        suggested_plan = Plausible.Billing.Plans.suggested_plan(subscriber, last_cycle)
 
-        true ->
-          nil
-      end
+        template =
+          PlausibleWeb.Email.over_limit_email(
+            subscriber,
+            last_cycle_usage,
+            last_cycle,
+            suggested_plan
+          )
+
+        Plausible.Mailer.send_email_safe(template)
+
+      _ ->
+        nil
     end
+  end
 
-    :ok
+  defp check_pageview_limit(subscriber, billing_mod) do
+    allowance = Plausible.Billing.Plans.allowance(subscriber.subscription)
+    {_, last_cycle} = billing_mod.last_two_billing_cycles(subscriber)
+
+    {last_last_cycle_usage, last_cycle_usage} =
+      billing_mod.last_two_billing_months_usage(subscriber)
+
+    if last_last_cycle_usage > allowance && last_cycle_usage > allowance do
+      {:over_limit, {last_cycle, last_cycle_usage, allowance}}
+    else
+      {:within_limit, {last_cycle, last_cycle_usage}}
+    end
+  end
+
+  defp check_site_limit(subscriber) do
+    allowance = subscriber.enterprise_plan.site_limit
+    total_sites = Plausible.Sites.count_owned_by(subscriber)
+
+    if total_sites >= allowance do
+      {:over_limit, {total_sites, allowance}}
+    else
+      {:within_limit, {total_sites, allowance}}
+    end
   end
 end
diff --git a/priv/repo/migrations/20211022084427_add_site_limit_to_enterprise_plans.exs b/priv/repo/migrations/20211022084427_add_site_limit_to_enterprise_plans.exs
new file mode 100644
index 0000000000000000000000000000000000000000..82879a8cd7d962f1e5c8fd303bed4aba6ff58bef
--- /dev/null
+++ b/priv/repo/migrations/20211022084427_add_site_limit_to_enterprise_plans.exs
@@ -0,0 +1,18 @@
+defmodule Plausible.Repo.Migrations.AddSiteLimitToEnterprisePlans do
+  use Ecto.Migration
+  use Plausible.Repo
+
+  def change do
+    alter table(:enterprise_plans) do
+      add :site_limit, :integer
+    end
+
+    flush()
+
+    Repo.update_all("enterprise_plans", set: [site_limit: 50])
+
+    alter table(:enterprise_plans) do
+      modify :site_limit, :integer, null: false
+    end
+  end
+end
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 02727def53c14ca89d67580101832f7b3f989864..dc2249a55de0ac00db48ec7b7959d3747ad34175 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -121,7 +121,8 @@ defmodule Plausible.Factory do
       paddle_plan_id: sequence(:paddle_plan_id, &"plan-#{&1}"),
       billing_interval: :monthly,
       monthly_pageview_limit: 1_000_000,
-      hourly_api_request_limit: 3000
+      hourly_api_request_limit: 3000,
+      site_limit: 100
     }
   end
 
diff --git a/test/workers/check_usage_test.exs b/test/workers/check_usage_test.exs
index 7441f64e8a77a3cef3fbd5f1e9e1cd3bef8ded4d..833593da3c54b77b6b4f44120cedce39a546bbc4 100644
--- a/test/workers/check_usage_test.exs
+++ b/test/workers/check_usage_test.exs
@@ -31,6 +31,9 @@ defmodule Plausible.Workers.CheckUsageTest do
   } do
     billing_stub =
       Plausible.Billing
+      |> stub(:last_two_billing_cycles, fn _user ->
+        {Date.range(Timex.today(), Timex.today()), Date.range(Timex.today(), Timex.today())}
+      end)
       |> stub(:last_two_billing_months_usage, fn _user -> {9_000, 11_000} end)
 
     insert(:subscription,
@@ -68,31 +71,64 @@ defmodule Plausible.Workers.CheckUsageTest do
     )
   end
 
-  test "checks usage for enterprise customer, sends usage information to enterprise@plausible.io",
-       %{
-         user: user
-       } do
-    billing_stub =
-      Plausible.Billing
-      |> stub(:last_two_billing_months_usage, fn _user -> {1_100_000, 1_100_000} end)
-      |> stub(:last_two_billing_cycles, fn _user ->
-        {Date.range(Timex.today(), Timex.today()), Date.range(Timex.today(), Timex.today())}
-      end)
+  describe "enterprise customers" do
+    test "checks billable pageview usage for enterprise customer, sends usage information to enterprise@plausible.io",
+         %{
+           user: user
+         } do
+      billing_stub =
+        Plausible.Billing
+        |> stub(:last_two_billing_months_usage, fn _user -> {1_100_000, 1_100_000} end)
+        |> stub(:last_two_billing_cycles, fn _user ->
+          {Date.range(Timex.today(), Timex.today()), Date.range(Timex.today(), Timex.today())}
+        end)
 
-    enterprise_plan = insert(:enterprise_plan, user: user, monthly_pageview_limit: 1_000_000)
+      enterprise_plan = insert(:enterprise_plan, user: user, monthly_pageview_limit: 1_000_000)
 
-    insert(:subscription,
-      user: user,
-      paddle_plan_id: enterprise_plan.paddle_plan_id,
-      last_bill_date: Timex.shift(Timex.today(), days: -1)
-    )
+      insert(:subscription,
+        user: user,
+        paddle_plan_id: enterprise_plan.paddle_plan_id,
+        last_bill_date: Timex.shift(Timex.today(), days: -1)
+      )
 
-    CheckUsage.perform(nil, billing_stub)
+      CheckUsage.perform(nil, billing_stub)
 
-    assert_email_delivered_with(
-      to: [{nil, "enterprise@plausible.io"}],
-      subject: "#{user.email} has outgrown their enterprise plan"
-    )
+      assert_email_delivered_with(
+        to: [{nil, "enterprise@plausible.io"}],
+        subject: "#{user.email} has outgrown their enterprise plan"
+      )
+    end
+
+    test "checks site limit for enterprise customer, sends usage information to enterprise@plausible.io",
+         %{
+           user: user
+         } do
+      billing_stub =
+        Plausible.Billing
+        |> stub(:last_two_billing_months_usage, fn _user -> {1, 1} end)
+        |> stub(:last_two_billing_cycles, fn _user ->
+          {Date.range(Timex.today(), Timex.today()), Date.range(Timex.today(), Timex.today())}
+        end)
+
+      enterprise_plan = insert(:enterprise_plan, user: user, site_limit: 2)
+
+      insert(:site, members: [user])
+      insert(:site, members: [user])
+      insert(:site, members: [user])
+
+      insert(:subscription,
+        user: user,
+        paddle_plan_id: enterprise_plan.paddle_plan_id,
+        last_bill_date: Timex.shift(Timex.today(), days: -1)
+      )
+
+      CheckUsage.perform(nil, billing_stub)
+
+      assert_email_delivered_with(
+        to: [{nil, "enterprise@plausible.io"}],
+        subject: "#{user.email} has outgrown their enterprise plan"
+      )
+    end
   end
 
   describe "timing" do