diff --git a/cmd/update.go b/cmd/update.go
index 8ffc485d425d25142f98e41cc8472833f520e078..655afe59aaec2811d8aa2b56ed72d3553cc0369b 100644
--- a/cmd/update.go
+++ b/cmd/update.go
@@ -10,6 +10,8 @@ import (
 	"k8s.io/client-go/pkg/api/errors"
 	"k8s.io/client-go/pkg/runtime"
 	"k8s.io/client-go/pkg/util/diff"
+
+	"github.com/ksonnet/kubecfg/utils"
 )
 
 const (
@@ -47,6 +49,8 @@ var updateCmd = &cobra.Command{
 			return err
 		}
 
+		utils.SortDepFirst(objs)
+
 		for _, obj := range objs {
 			desc := fmt.Sprintf("%s/%s", obj.GetKind(), fqName(obj))
 			glog.Info("Updating ", desc)
diff --git a/utils/sort.go b/utils/sort.go
new file mode 100644
index 0000000000000000000000000000000000000000..554f4c245113ac77f6bea8077ef0307769e656ff
--- /dev/null
+++ b/utils/sort.go
@@ -0,0 +1,59 @@
+package utils
+
+import (
+	"sort"
+
+	"k8s.io/client-go/pkg/api/unversioned"
+	"k8s.io/client-go/pkg/runtime"
+)
+
+var (
+	gkNamespace    = unversioned.GroupKind{Group: "", Kind: "Namespace"}
+	gkTpr          = unversioned.GroupKind{Group: "extensions", Kind: "ThirdPartyResource"}
+	gkStorageClass = unversioned.GroupKind{Group: "storage.k8s.io", Kind: "StorageClass"}
+
+	gkPod         = unversioned.GroupKind{Group: "", Kind: "Pod"}
+	gkJob         = unversioned.GroupKind{Group: "batch", Kind: "Job"}
+	gkDeployment  = unversioned.GroupKind{Group: "extensions", Kind: "Deployment"}
+	gkDaemonSet   = unversioned.GroupKind{Group: "extensions", Kind: "DaemonSet"}
+	gkStatefulSet = unversioned.GroupKind{Group: "apps", Kind: "StatefulSet"}
+)
+
+// These kinds all start pods.
+// TODO: expand this list.
+func isPodOrSimilar(gk unversioned.GroupKind) bool {
+	return gk == gkPod ||
+		gk == gkJob ||
+		gk == gkDeployment ||
+		gk == gkDaemonSet ||
+		gk == gkStatefulSet
+}
+
+// Arbitrary numbers used to do a simple topological sort of resources.
+// TODO: expand this list.
+func depTier(o *runtime.Unstructured) int {
+	gk := o.GroupVersionKind().GroupKind()
+	if gk == gkNamespace || gk == gkTpr || gk == gkStorageClass {
+		return 10
+	} else if isPodOrSimilar(gk) {
+		return 100
+	} else {
+		return 50
+	}
+}
+
+type dependentObjects []*runtime.Unstructured
+
+func (l dependentObjects) Len() int      { return len(l) }
+func (l dependentObjects) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
+func (l dependentObjects) Less(i, j int) bool {
+	return depTier(l[i]) < depTier(l[j])
+}
+
+// SortDepFirst *best-effort* sorts the objects so that known
+// dependencies appear earlier in the list.  The idea is to prevent
+// *some* of the "crash-restart" loops when creating inter-dependent
+// resources.
+func SortDepFirst(objs []*runtime.Unstructured) {
+	sort.Sort(dependentObjects(objs))
+}
diff --git a/utils/sort_test.go b/utils/sort_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..c579badc1d220122912ec0a194fb27ef952473c6
--- /dev/null
+++ b/utils/sort_test.go
@@ -0,0 +1,34 @@
+package utils
+
+import (
+	"testing"
+
+	"k8s.io/client-go/pkg/runtime"
+)
+
+func newObj(apiVersion, kind string) *runtime.Unstructured {
+	return &runtime.Unstructured{
+		Object: map[string]interface{}{
+			"apiVersion": apiVersion,
+			"kind":       kind,
+		},
+	}
+}
+
+func TestSort(t *testing.T) {
+	objs := []*runtime.Unstructured{
+		newObj("extensions/v1beta1", "Deployment"),
+		newObj("v1", "ConfigMap"),
+		newObj("v1", "Namespace"),
+		newObj("v1", "Service"),
+	}
+
+	SortDepFirst(objs)
+
+	if objs[0].GetKind() != "Namespace" {
+		t.Error("Namespace should be sorted first")
+	}
+	if objs[3].GetKind() != "Deployment" {
+		t.Error("Deployment should be sorted after other objects")
+	}
+}