diff --git a/app/styles/admin/analytics-subscriptions.sass b/app/styles/admin/analytics-subscriptions.sass
index 34206b2ca..b4a6eb0af 100644
--- a/app/styles/admin/analytics-subscriptions.sass
+++ b/app/styles/admin/analytics-subscriptions.sass
@@ -1,19 +1,50 @@
 #admin-analytics-subscriptions-view
 
-  .total-count
-    width: 33%
+  .big-stat
+    width: 25%
     float: left
+
+  .total-count
     color: green
   .remaining-count
-    width: 33%
-    float: left
     color: blue
   .cancelled-count
-    width: 33%
-    float: left
     color: red
+  .churn-count
+    color: orange
 
   .count
     font-size: 50pt
   .description
     font-size: 8pt
+
+  .line-graph-label
+    font-size: 10pt
+    font-weight: normal
+  .line-graph-container
+    height: 500px
+    width: 100%
+
+    // TODO: figure out why this is necessary
+    margin-bottom: 100px
+
+    .x.axis
+      font-size: 9pt
+      path
+        display: none
+    .y.axis
+      font-size: 9pt
+      path
+        display: none
+    .key-line
+      font-size: 9pt
+    .key-text
+      font-size: 9pt
+    .graph-point-info-container
+      display: none
+      position: absolute
+      padding: 10px
+      border: 1px solid black
+      z-index: 3
+      background-color: blanchedalmond
+      font-size: 10pt
diff --git a/app/templates/admin/analytics-subscriptions.jade b/app/templates/admin/analytics-subscriptions.jade
index 7369adf42..b1887b007 100644
--- a/app/templates/admin/analytics-subscriptions.jade
+++ b/app/templates/admin/analytics-subscriptions.jade
@@ -9,16 +9,32 @@ block content
       h1 Fetching subscriptions data...
     else
       div
-        .total-count
+        .big-stat.total-count
           div.description Total
           div.count= total
-        .remaining-count
+        .big-stat.remaining-count
           div.description Remaining
           div.count= total - cancelled
-        .cancelled-count
-          div.description cancelled
+        .big-stat.cancelled-count
+          div.description Cancelled
           div.count= cancelled
+        .big-stat.churn-count
+          div.description Monthly Churn
+          div.count #{monthlyChurn.toFixed(2)}%
       
+      each graph in analytics.graphs
+        .line-graph-container
+          each line in graph.lines
+            each point in line.points
+              .graph-point-info-container(data-pointid="#{point.pointID}")
+                div(style='font-weight:bold;') #{point.day}
+                each value in point.values
+                  div #{value}
+
+      div *Stripe APIs do not return information about inactive subs.
+
+      br
+        
       table.table.table-condensed.concepts-table
         thead
           tr
diff --git a/app/views/admin/AnalyticsSubscriptionsView.coffee b/app/views/admin/AnalyticsSubscriptionsView.coffee
index 886dda4e8..b1f60ae65 100644
--- a/app/views/admin/AnalyticsSubscriptionsView.coffee
+++ b/app/views/admin/AnalyticsSubscriptionsView.coffee
@@ -2,6 +2,10 @@ RootView = require 'views/core/RootView'
 template = require 'templates/admin/analytics-subscriptions'
 RealTimeCollection = require 'collections/RealTimeCollection'
 
+# TODO: Add revenue line
+# TODO: Add LTV line
+# TODO: Graphing code copied/mangled from campaign editor level view.  OMG, DRY.
+
 require 'vendor/d3'
 
 module.exports = class AnalyticsSubscriptionsView extends RootView
@@ -16,16 +20,24 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
 
   getRenderData: ->
     context = super()
+    context.analytics = @analytics
     context.subs = @subs ? []
     context.total = @total ? 0
     context.cancelled = @cancelled ? 0
+    context.monthlyChurn = @monthlyChurn ? 0.0
     context
 
+  afterRender: ->
+    super()
+    @updateAnalyticsGraphs()
+
   refreshData: ->
     return unless me.isAdmin()
+    @analytics = graphs: []
     @subs = []
     @total = 0
     @cancelled = 0
+    @monthlyChurn = 0.0
     onSuccess = (subs) =>
       subDayMap = {}
       for sub in subs
@@ -42,15 +54,270 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
           day: day
           started: subDayMap[day]['start']
           cancelled: subDayMap[day]['cancel'] or 0
-      @subs.sort (a, b) -> -a.day.localeCompare(b.day)
 
-      for i in [@subs.length - 1..0]
-        @total += @subs[i].started
-        @cancelled += @subs[i].cancelled
-        @subs[i].total = @total
+      @subs.sort (a, b) -> a.day.localeCompare(b.day)
+      startedLastMonth = 0
+      for sub, i in @subs
+        @total += sub.started
+        @cancelled += sub.cancelled
+        sub.total = @total
+        startedLastMonth += sub.started if @subs.length - i < 31
+      @monthlyChurn = @cancelled / startedLastMonth * 100.0
+
+      @updateAnalyticsGraphData()
       @render()
     @supermodel.addRequestResource('subscriptions', {
       url: '/db/subscription/-/subscriptions'
       method: 'GET'
       success: onSuccess
     }, 0).load()
+
+
+  updateAnalyticsGraphData: ->
+    # console.log 'updateAnalyticsGraphData'
+    # Build graphs based on available @analytics data
+    # Currently only one graph
+    @analytics.graphs = [graphID: 'total-subs', lines: []]
+
+    return unless @subs?.length > 0
+
+    # TODO: Where should this metadata live?
+    # TODO: lineIDs assumed to be unique across graphs
+    totalSubsID = 'total-subs'
+    startedSubsID = 'started-subs'
+    cancelledSubsID = 'cancelled-subs'
+    lineMetadata = {}
+    lineMetadata[totalSubsID] =
+      description: 'Total Active Subscriptions'
+      color: 'green'
+    lineMetadata[startedSubsID] =
+      description: 'New Subscriptions'
+      color: 'blue'
+    lineMetadata[cancelledSubsID] =
+      description: 'Cancelled Subscriptions'
+      color: 'red'
+
+    days = (sub.day for sub in @subs)
+    if days.length > 0
+      currentIndex = 0
+      currentDay = days[currentIndex]
+      currentDate = new Date(currentDay + "T00:00:00.000Z")
+      lastDay = days[days.length - 1]
+      while currentDay isnt lastDay
+        days.splice currentIndex, 0, currentDay if days[currentIndex] isnt currentDay
+        currentIndex++
+        currentDate.setUTCDate(currentDate.getUTCDate() + 1)
+        currentDay = currentDate.toISOString().substr(0, 10)
+
+    ## Totals
+
+    # Build line data
+    levelPoints = []
+    for sub, i in @subs
+      levelPoints.push
+        x: i
+        y: sub.total
+        day: sub.day
+        pointID: "#{totalSubsID}#{i}"
+        values: []
+
+    # Ensure points for each day
+    for day, i in days
+      if levelPoints.length <= i or levelPoints[i].day isnt day
+        prevY = if i > 0 then levelPoints[i - 1].y else 0.0
+        levelPoints.splice i, 0,
+          y: prevY
+          day: day
+          values: []
+      levelPoints[i].x = i
+      levelPoints[i].pointID = "#{totalSubsID}#{i}"
+
+    levelPoints.splice(0, levelPoints.length - 60) if levelPoints.length > 60
+
+    @analytics.graphs[0].lines.push
+      lineID: totalSubsID
+      enabled: true
+      points: levelPoints
+      description: lineMetadata[totalSubsID].description
+      lineColor: lineMetadata[totalSubsID].color
+      min: 0
+      max: d3.max(@subs, (d) -> d.total)
+
+    ## Started
+
+    # Build line data
+    levelPoints = []
+    for sub, i in @subs
+      levelPoints.push
+        x: i
+        y: sub.started
+        day: sub.day
+        pointID: "#{startedSubsID}#{i}"
+        values: []
+
+    # Ensure points for each day
+    for day, i in days
+      if levelPoints.length <= i or levelPoints[i].day isnt day
+        prevY = if i > 0 then levelPoints[i - 1].y else 0.0
+        levelPoints.splice i, 0,
+          y: prevY
+          day: day
+          values: []
+      levelPoints[i].x = i
+      levelPoints[i].pointID = "#{startedSubsID}#{i}"
+
+    levelPoints.splice(0, levelPoints.length - 60) if levelPoints.length > 60
+
+    @analytics.graphs[0].lines.push
+      lineID: startedSubsID
+      enabled: true
+      points: levelPoints
+      description: lineMetadata[startedSubsID].description
+      lineColor: lineMetadata[startedSubsID].color
+      min: 0
+      max: d3.max(@subs, (d) -> d.started)
+
+    ## Cancelled
+
+    # Build line data
+    levelPoints = []
+    for sub, i in @subs
+      levelPoints.push
+        x: i
+        y: sub.cancelled
+        day: sub.day
+        pointID: "#{cancelledSubsID}#{i}"
+        values: []
+
+    # Ensure points for each day
+    for day, i in days
+      if levelPoints.length <= i or levelPoints[i].day isnt day
+        prevY = if i > 0 then levelPoints[i - 1].y else 0.0
+        levelPoints.splice i, 0,
+          y: prevY
+          day: day
+          values: []
+      levelPoints[i].x = i
+      levelPoints[i].pointID = "#{cancelledSubsID}#{i}"
+
+    levelPoints.splice(0, levelPoints.length - 60) if levelPoints.length > 60
+
+    @analytics.graphs[0].lines.push
+      lineID: cancelledSubsID
+      enabled: true
+      points: levelPoints
+      description: lineMetadata[cancelledSubsID].description
+      lineColor: lineMetadata[cancelledSubsID].color
+      min: 0
+      max: d3.max(@subs, (d) -> d.started)
+
+  updateAnalyticsGraphs: ->
+    # Build d3 graphs
+    return unless @analytics?.graphs?.length > 0
+    containerSelector = '.line-graph-container'
+    # console.log 'updateAnalyticsGraphs', containerSelector, @analytics.graphs
+
+    margin = 20
+    keyHeight = 20
+    xAxisHeight = 20
+    yAxisWidth = 40
+    containerWidth = $(containerSelector).width()
+    containerHeight = $(containerSelector).height()
+
+    for graph in @analytics.graphs
+      graphLineCount = _.reduce graph.lines, ((sum, item) -> if item.enabled then sum + 1 else sum), 0
+      svg = d3.select(containerSelector).append("svg")
+        .attr("width", containerWidth)
+        .attr("height", containerHeight)
+      width = containerWidth - margin * 2 - yAxisWidth * graphLineCount
+      height = containerHeight - margin * 2 - xAxisHeight - keyHeight * graphLineCount
+      currentLine = 0
+      for line in graph.lines
+        continue unless line.enabled
+        xRange = d3.scale.linear().range([0, width]).domain([d3.min(line.points, (d) -> d.x), d3.max(line.points, (d) -> d.x)])
+        yRange = d3.scale.linear().range([height, 0]).domain([line.min, line.max])
+
+        # x-Axis and guideline once
+        if currentLine is 0
+          startDay = new Date(line.points[0].day)
+          endDay = new Date(line.points[line.points.length - 1].day)
+          xAxisRange = d3.time.scale()
+            .domain([startDay, endDay])
+            .range([0, width])
+          xAxis = d3.svg.axis()
+            .scale(xAxisRange)
+          svg.append("g")
+            .attr("class", "x axis")
+            .call(xAxis)
+            .selectAll("text")
+            .attr("dy", ".35em")
+            .attr("transform", "translate(" + (margin + yAxisWidth * (graphLineCount - 1)) + "," + (height + margin) + ")")
+            .style("text-anchor", "start")
+
+          # Horizontal guidelines
+          # svg.selectAll(".line")
+          #   .data([10, 30, 50, 70, 90])
+          #   .enter()
+          #   .append("line")
+          #   .attr("x1", margin + yAxisWidth * graphLineCount)
+          #   .attr("y1", (d) -> margin + yRange(d))
+          #   .attr("x2", margin + yAxisWidth * graphLineCount + width)
+          #   .attr("y2", (d) -> margin + yRange(d))
+          #   .attr("stroke", line.lineColor)
+          #   .style("opacity", "0.5")
+
+        # y-Axis
+        yAxisRange = d3.scale.linear().range([height, 0]).domain([line.min, line.max])
+        yAxis = d3.svg.axis()
+          .scale(yRange)
+          .orient("left")
+        svg.append("g")
+          .attr("class", "y axis")
+          .attr("transform", "translate(" + (margin + yAxisWidth * currentLine) + "," + margin + ")")
+          .style("color", line.lineColor)
+          .call(yAxis)
+          .selectAll("text")
+          .attr("y", 0)
+          .attr("x", 0)
+          .attr("fill", line.lineColor)
+          .style("text-anchor", "start")
+
+        # Key
+        svg.append("line")
+          .attr("x1", margin)
+          .attr("y1", margin + height + xAxisHeight + keyHeight * currentLine + keyHeight / 2)
+          .attr("x2", margin + 40)
+          .attr("y2", margin + height + xAxisHeight + keyHeight * currentLine + keyHeight / 2)
+          .attr("stroke", line.lineColor)
+          .attr("class", "key-line")
+        svg.append("text")
+          .attr("x", margin + 40 + 10)
+          .attr("y", margin + height + xAxisHeight + keyHeight * currentLine + (keyHeight + 10) / 2)
+          .attr("fill", line.lineColor)
+          .attr("class", "key-text")
+          .text(line.description)
+
+        # Path and points
+        svg.selectAll(".circle")
+          .data(line.points)
+          .enter()
+          .append("circle")
+          .attr("transform", "translate(" + (margin + yAxisWidth * graphLineCount) + "," + margin + ")")
+          .attr("cx", (d) -> xRange(d.x))
+          .attr("cy", (d) -> yRange(d.y))
+          .attr("r", 2)
+          .attr("fill", line.lineColor)
+          .attr("stroke-width", 1)
+          .attr("class", "graph-point")
+          .attr("data-pointid", (d) -> "#{line.lineID}#{d.x}")
+        d3line = d3.svg.line()
+          .x((d) -> xRange(d.x))
+          .y((d) -> yRange(d.y))
+          .interpolate("linear")
+        svg.append("path")
+          .attr("d", d3line(line.points))
+          .attr("transform", "translate(" + (margin + yAxisWidth * graphLineCount) + "," + margin + ")")
+          .style("stroke-width", 1)
+          .style("stroke", line.lineColor)
+          .style("fill", "none")
+        currentLine++
diff --git a/server/payments/subscription_handler.coffee b/server/payments/subscription_handler.coffee
index 9db6f8780..79005ea0f 100644
--- a/server/payments/subscription_handler.coffee
+++ b/server/payments/subscription_handler.coffee
@@ -37,8 +37,9 @@ class SubscriptionHandler extends Handler
 
     return @sendForbiddenError(res) unless req.user and req.user.isAdmin()
 
-    @subs ?= []
+    # @subs ?= []
     # return @sendSuccess(res, @subs) unless _.isEmpty(@subs)
+    @subs = []
 
     customersProcessed = 0
     nextBatch = (starting_after, done) =>