diff --git a/pkg/ingester/flush.go b/pkg/ingester/flush.go
index 2928029723bd2ad2bd16d35f19094831e1ff04e1..d45c11bea6377e60e74b600def3c854cd29f39d1 100644
--- a/pkg/ingester/flush.go
+++ b/pkg/ingester/flush.go
@@ -18,6 +18,7 @@ import (
 	"github.com/cortexproject/cortex/pkg/ingester/client"
 	"github.com/cortexproject/cortex/pkg/util"
 	"github.com/grafana/loki/pkg/chunkenc"
+	loki_util "github.com/grafana/loki/pkg/util"
 )
 
 var (
@@ -261,12 +262,12 @@ func (i *Ingester) flushChunks(ctx context.Context, fp model.Fingerprint, labelP
 
 	wireChunks := make([]chunk.Chunk, 0, len(cs))
 	for _, c := range cs {
-		firstTime, lastTime := c.chunk.Bounds()
+		firstTime, lastTime := loki_util.RoundToMilliseconds(c.chunk.Bounds())
 		c := chunk.NewChunk(
 			userID, fp, metric,
 			chunkenc.NewFacade(c.chunk),
-			model.TimeFromUnixNano(firstTime.UnixNano()),
-			model.TimeFromUnixNano(lastTime.UnixNano()),
+			firstTime,
+			lastTime,
 		)
 
 		start := time.Now()
diff --git a/pkg/storage/store.go b/pkg/storage/store.go
index 0ff8fccae6154ed6bae855fee4c1ea29a0c6c5e0..7e15663734ffec752180df950e848107b1e40706 100644
--- a/pkg/storage/store.go
+++ b/pkg/storage/store.go
@@ -11,6 +11,7 @@ import (
 	"github.com/grafana/loki/pkg/iter"
 	"github.com/grafana/loki/pkg/logproto"
 	"github.com/grafana/loki/pkg/logql"
+	"github.com/grafana/loki/pkg/util"
 	"github.com/opentracing/opentracing-go"
 	"github.com/prometheus/common/model"
 	"github.com/prometheus/prometheus/pkg/labels"
@@ -56,7 +57,7 @@ func (s *store) LazyQuery(ctx context.Context, req *logproto.QueryRequest) (iter
 		}
 
 		matchers = append(matchers, nameLabelMatcher)
-		from, through := model.TimeFromUnixNano(req.Start.UnixNano()), model.TimeFromUnixNano(req.End.UnixNano())
+		from, through := util.RoundToMilliseconds(req.Start, req.End)
 		chks, fetchers, err := s.GetChunkRefs(ctx, from, through, matchers...)
 		if err != nil {
 			return nil, err
diff --git a/pkg/util/conv.go b/pkg/util/conv.go
index bc95638cb8ee0e9909aa5b8c6e18ee0896093e6d..54e31dcd4f9e4ab64e1ac41c770aa835931ae78e 100644
--- a/pkg/util/conv.go
+++ b/pkg/util/conv.go
@@ -1,8 +1,10 @@
 package util
 
 import (
+	"math"
 	"sort"
 	"strings"
+	"time"
 
 	"github.com/cortexproject/cortex/pkg/ingester/client"
 	"github.com/grafana/loki/pkg/logql"
@@ -41,3 +43,10 @@ func ModelLabelSetToMap(m model.LabelSet) map[string]string {
 	}
 	return result
 }
+
+// RoundToMilliseconds returns milliseconds precision time from nanoseconds.
+// from will be rounded down to the nearest milliseconds while through is rounded up.
+func RoundToMilliseconds(from, through time.Time) (model.Time, model.Time) {
+	return model.Time(int64(math.Floor(float64(from.UnixNano()) / float64(time.Millisecond)))),
+		model.Time(int64(math.Ceil(float64(through.UnixNano()) / float64(time.Millisecond))))
+}
diff --git a/pkg/util/conv_test.go b/pkg/util/conv_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..ab27d230b26f9c98badf42b25fafd9819ad2a7f8
--- /dev/null
+++ b/pkg/util/conv_test.go
@@ -0,0 +1,59 @@
+package util
+
+import (
+	"reflect"
+	"testing"
+	"time"
+
+	"github.com/prometheus/common/model"
+)
+
+func TestRoundToMilliseconds(t *testing.T) {
+	tests := []struct {
+		name        string
+		from        time.Time
+		through     time.Time
+		wantFrom    model.Time
+		wantThrough model.Time
+	}{
+		{
+			"0",
+			time.Unix(0, 0),
+			time.Unix(0, 1),
+			model.Time(0),
+			model.Time(1),
+		},
+		{
+			"equal",
+			time.Unix(0, time.Millisecond.Nanoseconds()),
+			time.Unix(0, time.Millisecond.Nanoseconds()),
+			model.Time(1),
+			model.Time(1),
+		},
+		{
+			"exact",
+			time.Unix(0, time.Millisecond.Nanoseconds()),
+			time.Unix(0, 2*time.Millisecond.Nanoseconds()),
+			model.Time(1),
+			model.Time(2),
+		},
+		{
+			"rounding",
+			time.Unix(0, time.Millisecond.Nanoseconds()+10),
+			time.Unix(0, 2*time.Millisecond.Nanoseconds()+10),
+			model.Time(1),
+			model.Time(3),
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			from, through := RoundToMilliseconds(tt.from, tt.through)
+			if !reflect.DeepEqual(from, tt.wantFrom) {
+				t.Errorf("RoundToMilliseconds() from = %v, want %v", from, tt.wantFrom)
+			}
+			if !reflect.DeepEqual(through, tt.wantThrough) {
+				t.Errorf("RoundToMilliseconds() through = %v, want %v", through, tt.wantThrough)
+			}
+		})
+	}
+}