diff --git a/controllers/drupalsite_controller_test.go b/controllers/drupalsite_controller_test.go
index 98258e1d7674d5f562a85d4dbc42289ef3b1a472..85b2eefa1d166a67f3b2f8fa51fbe5284c070e97 100644
--- a/controllers/drupalsite_controller_test.go
+++ b/controllers/drupalsite_controller_test.go
@@ -495,17 +495,17 @@ var _ = Describe("DrupalSite controller", func() {
 					return k8sClient.Get(ctx, key, &cr)
 				}, timeout, interval).Should(Succeed())
 
-				By("Adding label to namespace")
+				By("Adding user-project label to namespace")
 				Eventually(func() error {
 					k8sClient.Get(ctx, types.NamespacedName{Name: key.Namespace}, &namespace)
 					namespace.Labels = map[string]string{"okd.cern.ch/user-project": "true"}
 					return k8sClient.Update(ctx, &namespace)
 				}, timeout, interval).Should(Succeed())
 
-				By("Adding annotations to namespace")
+				By("Adding blocked label to namespace")
 				Eventually(func() error {
 					k8sClient.Get(ctx, types.NamespacedName{Name: key.Namespace}, &namespace)
-					namespace.Annotations = map[string]string{"blocked.webservices.cern.ch/blocked-timestamp": "2021-08-11T10:20:00+00:00", "blocked.webservices.cern.ch/reason": "Blocked due to security reason"}
+					namespace.Labels["okd.cern.ch/project-blocked"] = "true"
 					return k8sClient.Update(ctx, &namespace)
 				}, timeout, interval).Should(Succeed())
 
@@ -516,11 +516,10 @@ var _ = Describe("DrupalSite controller", func() {
 					return *deploy.Spec.Replicas == 0
 				}, timeout, interval).Should(BeTrue())
 
-				By("Removing annotations to namespace")
+				By("Removing blocked label from namespace")
 				Eventually(func() error {
 					k8sClient.Get(ctx, types.NamespacedName{Name: key.Namespace}, &namespace)
-					delete(namespace.Annotations, "blocked.webservices.cern.ch/blocked-timestamp")
-					delete(namespace.Annotations, "blocked.webservices.cern.ch/reason")
+					delete(namespace.Labels, "okd.cern.ch/project-blocked")
 					return k8sClient.Update(ctx, &namespace)
 				}, timeout, interval).Should(Succeed())
 
diff --git a/controllers/reconciler_common.go b/controllers/reconciler_common.go
index eac4c371de2528ebbefe7369e87e37e5c145c65f..b37a272155fea3e00ddc7d5708ce14ac4ad832db 100644
--- a/controllers/reconciler_common.go
+++ b/controllers/reconciler_common.go
@@ -59,6 +59,8 @@ type DeploymentConfig struct {
 	drupalLogsResources  corev1.ResourceRequirements
 }
 
+const projectBlockedLabel = "okd.cern.ch/project-blocked"
+
 func setReady(drp *webservicesv1a1.DrupalSite) (update bool) {
 	return drp.Status.Conditions.SetCondition(status.Condition{
 		Type:   "Ready",
@@ -455,21 +457,28 @@ func backupListUpdateNeeded(veleroBackupsList []velerov1.Backup, statusBackupsLi
 
 // expectedDeploymentReplicas calculates expected replicas of deployment
 func expectedDeploymentReplicas(currentnamespace *corev1.Namespace, qosClass webservicesv1a1.QoSClass) (int32, error) {
-	_, isBlockedTimestampAnnotationSet := currentnamespace.Annotations["blocked.webservices.cern.ch/blocked-timestamp"]
-	_, isBlockedReasonAnnotationSet := currentnamespace.Annotations["blocked.webservices.cern.ch/reason"]
-	blocked := isBlockedTimestampAnnotationSet && isBlockedReasonAnnotationSet
-	notBlocked := !isBlockedTimestampAnnotationSet && !isBlockedReasonAnnotationSet
-	switch {
-	case !blocked && !notBlocked:
-		return 0, fmt.Errorf("both annotations blocked.webservices.cern.ch/blocked-timestamp and blocked.webservices.cern.ch/reason should be added/removed to block/unblock")
-	case blocked:
+	// websites in blocked projects should be scaled to zero replicas
+	// this causes HAProxy routers to return "503 Application not available"
+	if projectBlocked(*currentnamespace) {
 		return 0, nil
-	default:
-		if qosClass == webservicesv1a1.QoSCritical {
-			return 3, nil
-		}
-		return 1, nil
 	}
+
+	// websites with "critical" QoS should be scaled to three replicas,
+	// so they have one pod per availability zone
+	if qosClass == webservicesv1a1.QoSCritical {
+		return 3, nil
+	}
+
+	// regular websites should have a single replica
+	return 1, nil
+}
+
+func projectBlocked(namespace corev1.Namespace) bool {
+	value, found := namespace.ObjectMeta.Labels[projectBlockedLabel]
+	if found && value == "true" {
+		return true
+	}
+	return false
 }
 
 // containerExists checks if a container exists on the deployment